// Copyright 2020 The Tint Authors.
//
// 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.

#ifndef SRC_WRITER_SPIRV_BUILDER_H_
#define SRC_WRITER_SPIRV_BUILDER_H_

#include <functional>
#include <string>
#include <unordered_map>
#include <vector>

#include "src/ast/module.h"
#include "src/writer/spirv/instruction.h"

namespace tint {
namespace writer {
namespace spirv {

/// Builder class to create SPIR-V instructions from a module.
class Builder {
 public:
  /// Constructor
  Builder();
  ~Builder();

  /// Generates the SPIR-V instructions for the given module
  /// @param module the module to generate from
  /// @returns true if the SPIR-V was successfully built
  bool Build(const ast::Module& module);

  /// @returns the error string or blank if no error was reported.
  const std::string& error() const { return error_; }

  /// @returns the number of uint32_t's needed to make up the results
  uint32_t total_size() const;

  /// @returns the id bound for this module
  uint32_t id_bound() const { return next_id_; }

  /// @returns the next id to be used
  uint32_t next_id() {
    auto id = next_id_;
    next_id_ += 1;
    return id;
  }

  /// Sets the id for a given function name
  /// @param name the name to set
  /// @param id the id to set
  void set_func_name_to_id(const std::string& name, uint32_t id) {
    func_name_to_id_[name] = id;
  }

  /// Retrives the id for the given function name
  /// @returns the id for the given name or 0 on failure
  uint32_t id_for_func_name(const std::string& name) {
    if (func_name_to_id_.count(name) == 0) {
      return 0;
    }
    return func_name_to_id_[name];
  }

  /// Iterates over all the instructions in the correct order and calls the
  /// given callback
  /// @param cb the callback to execute
  void iterate(std::function<void(const Instruction&)> cb) const;

  /// Adds an instruction to the preamble
  /// @param op the op to set
  /// @param operands the operands for the instruction
  void push_preamble(spv::Op op, const std::vector<Operand>& operands) {
    preamble_.push_back(Instruction{op, operands});
  }
  /// @returns the preamble
  const std::vector<Instruction>& preamble() const { return preamble_; }
  /// Adds an instruction to the debug
  /// @param op the op to set
  /// @param operands the operands for the instruction
  void push_debug(spv::Op op, const std::vector<Operand>& operands) {
    debug_.push_back(Instruction{op, operands});
  }
  /// @returns the debug instructions
  const std::vector<Instruction>& debug() const { return debug_; }
  /// Adds an instruction to the types
  /// @param op the op to set
  /// @param operands the operands for the instruction
  void push_type(spv::Op op, const std::vector<Operand>& operands) {
    types_.push_back(Instruction{op, operands});
  }
  /// @returns the type instructions
  const std::vector<Instruction>& type() const { return types_; }
  /// Adds an instruction to the instruction list
  /// @param op the op to set
  /// @param operands the operands for the instruction
  void push_inst(spv::Op op, const std::vector<Operand>& operands) {
    instructions_.push_back(Instruction{op, operands});
  }
  /// @returns the instruction list
  const std::vector<Instruction>& inst() const { return instructions_; }
  /// Adds an instruction to the annotations
  /// @param op the op to set
  /// @param operands the operands for the instruction
  void push_annot(spv::Op op, const std::vector<Operand>& operands) {
    annotations_.push_back(Instruction{op, operands});
  }
  /// @returns the annotations
  const std::vector<Instruction>& annot() const { return annotations_; }

  /// Generates an entry point instruction
  /// @param ep the entry point
  /// @returns true if the instruction was generated, false otherwise
  bool GenerateEntryPoint(ast::EntryPoint* ep);
  /// Generates an import instruction
  /// @param imp the import
  void GenerateImport(ast::Import* imp);

 private:
  Operand result_op();

  std::string error_;
  uint32_t next_id_ = 1;
  std::vector<Instruction> preamble_;
  std::vector<Instruction> debug_;
  std::vector<Instruction> types_;
  std::vector<Instruction> instructions_;
  std::vector<Instruction> annotations_;

  std::unordered_map<std::string, uint32_t> import_name_to_id_;
  std::unordered_map<std::string, uint32_t> func_name_to_id_;
};

}  // namespace spirv
}  // namespace writer
}  // namespace tint

#endif  // SRC_WRITER_SPIRV_BUILDER_H_
