// Copyright (c) 2016 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "module.h"

#include <algorithm>

#include "operand.h"
#include "reflect.h"

namespace spvtools {
namespace ir {

std::vector<Instruction*> Module::GetTypes() {
  std::vector<Instruction*> insts;
  for (uint32_t i = 0; i < types_values_.size(); ++i) {
    if (IsTypeInst(types_values_[i]->opcode()))
      insts.push_back(types_values_[i].get());
  }
  return insts;
};

std::vector<const Instruction*> Module::GetTypes() const {
  std::vector<const Instruction*> insts;
  for (uint32_t i = 0; i < types_values_.size(); ++i) {
    if (IsTypeInst(types_values_[i]->opcode()))
      insts.push_back(types_values_[i].get());
  }
  return insts;
};

std::vector<Instruction*> Module::GetConstants() {
  std::vector<Instruction*> insts;
  for (uint32_t i = 0; i < types_values_.size(); ++i) {
    if (IsConstantInst(types_values_[i]->opcode()))
      insts.push_back(types_values_[i].get());
  }
  return insts;
};

std::vector<const Instruction*> Module::GetConstants() const {
  std::vector<const Instruction*> insts;
  for (uint32_t i = 0; i < types_values_.size(); ++i) {
    if (IsConstantInst(types_values_[i]->opcode()))
      insts.push_back(types_values_[i].get());
  }
  return insts;
};

void Module::ForEachInst(const std::function<void(Instruction*)>& f,
                         bool run_on_debug_line_insts) {
#define DELEGATE(i) i->ForEachInst(f, run_on_debug_line_insts)
  for (auto& i : capabilities_) DELEGATE(i);
  for (auto& i : extensions_) DELEGATE(i);
  for (auto& i : ext_inst_imports_) DELEGATE(i);
  if (memory_model_) DELEGATE(memory_model_);
  for (auto& i : entry_points_) DELEGATE(i);
  for (auto& i : execution_modes_) DELEGATE(i);
  for (auto& i : debugs_) DELEGATE(i);
  for (auto& i : annotations_) DELEGATE(i);
  for (auto& i : types_values_) DELEGATE(i);
  for (auto& i : functions_) DELEGATE(i);
#undef DELEGATE
}

void Module::ForEachInst(const std::function<void(const Instruction*)>& f,
                         bool run_on_debug_line_insts) const {
#define DELEGATE(i)                        \
  static_cast<const Instruction*>(i.get()) \
      ->ForEachInst(f, run_on_debug_line_insts)
  for (auto& i : capabilities_) DELEGATE(i);
  for (auto& i : extensions_) DELEGATE(i);
  for (auto& i : ext_inst_imports_) DELEGATE(i);
  if (memory_model_) DELEGATE(memory_model_);
  for (auto& i : entry_points_) DELEGATE(i);
  for (auto& i : execution_modes_) DELEGATE(i);
  for (auto& i : debugs_) DELEGATE(i);
  for (auto& i : annotations_) DELEGATE(i);
  for (auto& i : types_values_) DELEGATE(i);
  for (auto& i : functions_) {
    static_cast<const Function*>(i.get())
        ->ForEachInst(f, run_on_debug_line_insts);
  }
#undef DELEGATE
}

void Module::ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const {
  binary->push_back(header_.magic_number);
  binary->push_back(header_.version);
  // TODO(antiagainst): should we change the generator number?
  binary->push_back(header_.generator);
  binary->push_back(header_.bound);
  binary->push_back(header_.reserved);

  auto write_inst = [this, binary, skip_nop](const Instruction* i) {
    if (!(skip_nop && i->IsNop())) i->ToBinaryWithoutAttachedDebugInsts(binary);
  };
  ForEachInst(write_inst, true);
}

uint32_t Module::ComputeIdBound() const {
  uint32_t highest = 0;

  ForEachInst([&highest](const Instruction* inst) {
    for (const auto& operand : *inst) {
      if (spvIsIdType(operand.type)) {
        highest = std::max(highest, operand.words[0]);
      }
    }
  }, true /* scan debug line insts as well */);

  return highest + 1;
}

}  // namespace ir
}  // namespace spvtools
