// 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.

#ifndef LIBSPIRV_TEST_OPT_ASSEMBLY_BUILDER
#define LIBSPIRV_TEST_OPT_ASSEMBLY_BUILDER

#include <algorithm>
#include <cstdint>
#include <sstream>
#include <string>
#include <unordered_set>
#include <vector>

namespace spvtools {

// A simple SPIR-V assembly code builder for test uses. It builds an SPIR-V
// assembly module from vectors of assembly strings. It allows users to add
// instructions to the main function and the type-constants-globals section
// directly. It relies on OpName instructions and friendly-name disassembling
// to keep the ID names unchanged after assembling.
//
// An assembly module is divided into several sections, matching with the
// SPIR-V Logical Layout:
//  Global Preamble:
//    OpCapability instructions;
//    OpExtension instructions and OpExtInstImport instructions;
//    OpMemoryModel instruction;
//    OpEntryPoint and OpExecutionMode instruction;
//    OpString, OpSourceExtension, OpSource and OpSourceContinued instructions.
//  Names:
//    OpName instructions.
//  Annotations:
//    OpDecorate, OpMemberDecorate, OpGroupDecorate, OpGroupMemberDecorate and
//    OpDecorationGroup.
//  Types, Constants and Global variables:
//    Types, constants and global variables declaration instructions.
//  Main Function:
//    Main function instructions.
//  Main Function Postamble:
//    The return and function end instructions.
//
// The assembly code is built by concatenating all the strings in the above
// sections.
//
// Users define the contents in section <Type, Constants and Global Variables>
// and <Main Function>. The <Names> section is to hold the names for IDs to
// keep them unchanged before and after assembling. All defined IDs to be added
// to this code builder will be assigned with a global name through OpName
// instruction. The name is extracted from the definition instruction.
//  E.g. adding instruction: %var_a = OpConstant %int 2, will also add an
//  instruction: OpName %var_a, "var_a".
//
// Note that the name must not be used on more than one defined IDs and
// friendly-name disassembling must be enabled so that OpName instructions will
// be respected.
class AssemblyBuilder {
  // The base ID value for spec constants.
  static const uint32_t SPEC_ID_BASE = 200;

 public:
  // Initalize a minimal SPIR-V assembly code as the template. The minimal
  // module contains an empty main function and some predefined names for the
  // main function.
  AssemblyBuilder()
      : spec_id_counter_(SPEC_ID_BASE),
        global_preamble_({
            // clang-format off
                  "OpCapability Shader",
                  "OpCapability Float64",
             "%1 = OpExtInstImport \"GLSL.std.450\"",
                  "OpMemoryModel Logical GLSL450",
                  "OpEntryPoint Vertex %main \"main\"",
            // clang-format on
        }),
        names_(),
        annotations_(),
        types_consts_globals_(),
        main_func_(),
        main_func_postamble_({
            "OpReturn",
            "OpFunctionEnd",
        }) {
    AppendTypesConstantsGlobals({
        "%void = OpTypeVoid",
        "%main_func_type = OpTypeFunction %void",
    });
    AppendInMain({
        "%main = OpFunction %void None %main_func_type",
        "%main_func_entry_block = OpLabel",
    });
  }

  // Appends OpName instructions to this builder. Instrcution strings that do
  // not start with 'OpName ' will be skipped. Returns the references of this
  // assembly builder.
  AssemblyBuilder& AppendNames(const std::vector<std::string>& vec_asm_code) {
    for (auto& inst_str : vec_asm_code) {
      if (inst_str.find("OpName ") == 0) {
        names_.push_back(inst_str);
      }
    }
    return *this;
  }

  // Appends instructions to the types-constants-globals section and returns
  // the reference of this assembly builder. IDs defined in the given code will
  // be added to the Names section and then be registered with OpName
  // instruction. Corresponding decoration instruction will be added for spec
  // constants defined with opcode: 'OpSpecConstant'.
  AssemblyBuilder& AppendTypesConstantsGlobals(
      const std::vector<std::string>& vec_asm_code) {
    AddNamesForResultIDsIn(vec_asm_code);
    // Check spec constants defined with OpSpecConstant.
    for (auto& inst_str : vec_asm_code) {
      if (inst_str.find("= OpSpecConstant ") != std::string::npos ||
          inst_str.find("= OpSpecConstantTrue ") != std::string::npos ||
          inst_str.find("= OpSpecConstantFalse ") != std::string::npos) {
        AddSpecIDFor(GetResultIDName(inst_str));
      }
    }
    types_consts_globals_.insert(types_consts_globals_.end(),
                                 vec_asm_code.begin(), vec_asm_code.end());
    return *this;
  }

  // Appends instructions to the main function block, which is already labelled
  // with "main_func_entry_block". Returns the reference of this assembly
  // builder. IDs defined in the given code will be added to the Names section
  // and then be registered with OpName instruction.
  AssemblyBuilder& AppendInMain(const std::vector<std::string>& vec_asm_code) {
    AddNamesForResultIDsIn(vec_asm_code);
    main_func_.insert(main_func_.end(), vec_asm_code.begin(),
                      vec_asm_code.end());
    return *this;
  }

  // Appends annotation instructions to the annotation section, and returns the
  // reference of this assembly builder.
  AssemblyBuilder& AppendAnnotations(
      const std::vector<std::string>& vec_annotations) {
    annotations_.insert(annotations_.end(), vec_annotations.begin(),
                        vec_annotations.end());
    return *this;
  }

  // Pre-pends string to the preamble of the module. Useful for EFFCEE checks.
  AssemblyBuilder& PrependPreamble(const std::vector<std::string>& preamble) {
    preamble_.insert(preamble_.end(), preamble.begin(), preamble.end());
    return *this;
  }

  // Get the SPIR-V assembly code as string.
  std::string GetCode() const {
    std::ostringstream ss;
    for (const auto& line : preamble_) {
      ss << line << std::endl;
    }
    for (const auto& line : global_preamble_) {
      ss << line << std::endl;
    }
    for (const auto& line : names_) {
      ss << line << std::endl;
    }
    for (const auto& line : annotations_) {
      ss << line << std::endl;
    }
    for (const auto& line : types_consts_globals_) {
      ss << line << std::endl;
    }
    for (const auto& line : main_func_) {
      ss << line << std::endl;
    }
    for (const auto& line : main_func_postamble_) {
      ss << line << std::endl;
    }
    return ss.str();
  }

 private:
  // Adds a given name to the Name section with OpName. If the given name has
  // been added before, does nothing.
  void AddOpNameIfNotExist(const std::string& id_name) {
    if (!used_names_.count(id_name)) {
      std::stringstream opname_inst;
      opname_inst << "OpName "
                  << "%" << id_name << " \"" << id_name << "\"";
      names_.emplace_back(opname_inst.str());
      used_names_.insert(id_name);
    }
  }

  // Adds the names in a vector of assembly code strings to the Names section.
  // If a '=' sign is found in an instruction, this instruction will be treated
  // as an ID defining instruction. The ID name used in the instruction will be
  // extracted and added to the Names section.
  void AddNamesForResultIDsIn(const std::vector<std::string>& vec_asm_code) {
    for (const auto& line : vec_asm_code) {
      std::string name = GetResultIDName(line);
      if (!name.empty()) {
        AddOpNameIfNotExist(name);
      }
    }
  }

  // Adds an OpDecorate SpecId instruction for the given ID name.
  void AddSpecIDFor(const std::string& id_name) {
    std::stringstream decorate_inst;
    decorate_inst << "OpDecorate "
                  << "%" << id_name << " SpecId " << spec_id_counter_;
    spec_id_counter_ += 1;
    annotations_.emplace_back(decorate_inst.str());
  }

  // Extracts the ID name from a SPIR-V assembly instruction string. If the
  // instruction is an ID-defining instruction (has result ID), returns the
  // name of the result ID in string. If the instruction does not have result
  // ID, returns an empty string.
  std::string GetResultIDName(const std::string inst_str) {
    std::string name;
    if (inst_str.find('=') != std::string::npos) {
      size_t assign_sign = inst_str.find('=');
      name = inst_str.substr(0, assign_sign);
      name.erase(remove_if(name.begin(), name.end(),
                           [](char c) { return c == ' ' || c == '%'; }),
                 name.end());
    }
    return name;
  }

  uint32_t spec_id_counter_;
  // User-defined preamble.
  std::vector<std::string> preamble_;
  // The vector that contains common preambles shared across all test SPIR-V
  // code.
  std::vector<std::string> global_preamble_;
  // The vector that contains OpName instructions.
  std::vector<std::string> names_;
  // The vector that contains annotation instructions.
  std::vector<std::string> annotations_;
  // The vector that contains the code to declare types, constants and global
  // variables (aka. the Types-Constants-Globals section).
  std::vector<std::string> types_consts_globals_;
  // The vector that contains the code in main function's entry block.
  std::vector<std::string> main_func_;
  // The vector that contains the postamble of main function body.
  std::vector<std::string> main_func_postamble_;
  // All of the defined variable names.
  std::unordered_set<std::string> used_names_;
};

}  // namespace spvtools

#endif  // LIBSPIRV_TEST_OPT_ASSEMBLY_BUILDER
