// Copyright 2023 Google LLC
//
// 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
//
//     https://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 MPACT_SIM_DECODER_INSTRUCTION_SET_H_
#define MPACT_SIM_DECODER_INSTRUCTION_SET_H_

#include <memory>
#include <string>
#include <tuple>
#include <vector>

#include "absl/container/btree_map.h"
#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/decoder/bundle.h"
#include "mpact/sim/decoder/instruction.h"
#include "mpact/sim/decoder/opcode.h"
#include "mpact/sim/decoder/resource.h"
#include "mpact/sim/decoder/slot.h"

namespace mpact {
namespace sim {
namespace machine_description {
namespace instruction_set {

// This class represents the top level of an isa decode declaration. The
// InstructionSet class contains (has-a) bundle, which is the top level bundle
// of the instruction set architecture. Its name is the same as that of the
// InstructionSet.
class InstructionSet {
 public:
  struct StringPair {
    std::string h_output;
    std::string cc_output;
  };

  // Constructor and destructor.
  explicit InstructionSet(absl::string_view name);
  virtual ~InstructionSet();

  // Add bundle and slot to instruction set.
  void AddBundle(Bundle* bundle);
  void AddSlot(Slot* slot);
  void PrependNamespace(absl::string_view namespace_name);

  // Look up bundle and slot names and return pointers to their respective
  // objects. If not found, return nullptr.
  Bundle* GetBundle(absl::string_view) const;
  Slot* GetSlot(absl::string_view) const;
  // Compute the set of reachable bundles and slots.
  void ComputeSlotAndBundleOrders();
  // Analyze the resource use in the opcodes in the slots. This is done to
  // determine which resources must be modeled by complex resource types vs
  // simple resource types.
  absl::Status AnalyzeResourceUse();
  // Return strings containing class declarations, definitions, and opcode enum
  // class.
  std::string GenerateClassDeclarations(absl::string_view file_name,
                                        absl::string_view opcode_file_name,
                                        absl::string_view encoding_type) const;
  std::string GenerateClassDefinitions(absl::string_view include_file,
                                       absl::string_view encoding_type) const;
  std::tuple<std::string, std::string> GenerateEncClasses(
      absl::string_view file_name, absl::string_view opcode_file_name,
      absl::string_view encoder_type) const;
  // This method is static, as it considers all the instruction sets that were
  // defined.
  StringPair GenerateEnums(absl::string_view file_name);

  void AddInstruction(Instruction* inst) {
    if (instruction_map_.contains(inst->opcode()->name())) return;
    instruction_map_.emplace(inst->opcode()->name(), inst);
  }

  // Getters and setters.
  std::vector<std::string>& namespaces() { return namespaces_; }
  const std::string& name() const { return name_; }
  const std::string& pascal_name() const { return pascal_name_; }
  void set_bundle(Bundle* bundle) { bundle_ = bundle; }
  Bundle* bundle() { return bundle_; }
  OpcodeFactory* opcode_factory() const { return opcode_factory_.get(); }
  ResourceFactory* resource_factory() const { return resource_factory_.get(); }

  absl::flat_hash_map<std::string, Bundle*>& bundle_map() {
    return bundle_map_;
  }
  absl::flat_hash_map<std::string, Slot*>& slot_map() { return slot_map_; }

  // Maps from operand names to enum values.
  absl::flat_hash_map<std::string, int>& pred_op_map() { return pred_op_map_; }
  absl::flat_hash_map<std::string, int>& source_op_map() {
    return source_op_map_;
  }
  absl::flat_hash_map<std::string, int>& list_source_op_map() {
    return list_source_op_map_;
  }
  absl::flat_hash_map<std::string, int>& dest_op_map() { return dest_op_map_; }
  absl::flat_hash_map<std::string, int>& list_dest_op_map() {
    return list_dest_op_map_;
  }

  std::string GenerateEncodingFunctions() const;

 private:
  std::string GenerateOperandEncoder(int position, absl::string_view op_name,
                                     const OperandLocator& locator,
                                     const Opcode* opcode) const;
  // Add bundle and slot to list of classes that need to be generated.
  void AddToBundleOrder(Bundle*);
  void AddToSlotOrder(Slot*);
  // Data members.
  std::vector<std::string> namespaces_;
  std::vector<Slot*> slot_order_;
  std::vector<Bundle*> bundle_order_;
  std::unique_ptr<OpcodeFactory> opcode_factory_;
  std::unique_ptr<ResourceFactory> resource_factory_;
  std::string name_;
  // Name in PascalCase.
  std::string pascal_name_;
  Bundle* bundle_ = nullptr;
  // Map from instruction name to pointer.
  absl::btree_map<std::string, Instruction*> instruction_map_;
  // Maps from names to bundle/slot pointers.
  absl::flat_hash_map<std::string, Bundle*> bundle_map_;
  absl::flat_hash_map<std::string, Slot*> slot_map_;
  // Maps from operand names to enum values.
  absl::flat_hash_map<std::string, int> pred_op_map_;
  absl::flat_hash_map<std::string, int> source_op_map_;
  absl::flat_hash_map<std::string, int> list_source_op_map_;
  absl::flat_hash_map<std::string, int> dest_op_map_;
  absl::flat_hash_map<std::string, int> list_dest_op_map_;
};

}  // namespace instruction_set
}  // namespace machine_description
}  // namespace sim
}  // namespace mpact

#endif  // MPACT_SIM_DECODER_INSTRUCTION_SET_H_
