// 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_OPCODE_H_
#define MPACT_SIM_DECODER_OPCODE_H_

#include <functional>
#include <string>
#include <utility>
#include <variant>
#include <vector>

#include "absl/container/btree_set.h"
#include "absl/container/flat_hash_map.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/decoder/format_name.h"
#include "mpact/sim/decoder/resource.h"
#include "mpact/sim/decoder/template_expression.h"

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

// An instance of the Opcode class represents an individual instruction opcode
// in the instruction set. The Opcode name has to be unique within the
// instruction set. In addition to having a name, the opcode also has an
// optional predicate operand name, a (possibly empty) list of source operand
// names, and a (possibly empty) list of destination operand names.
//
// Opcodes are created using the OpcodeFactory factory class. Each opcode is
// assigned a unique (within the OpcodeFactory) value that is used to define
// the value of the corresponding class enum entry in the generated code. This
// value is unrelated to any value of the "opcode" field in the instruction
// encoding.
class DestinationOperand {
 public:
  // Operand latency is defined by the expression.
  DestinationOperand(std::string name, TemplateExpression *expression)
      : name_(std::move(name)),
        pascal_case_name_(ToPascalCase(name_)),
        expression_(expression) {}
  // Operand latency is a constant.
  DestinationOperand(std::string name, int latency)
      : name_(std::move(name)),
        pascal_case_name_(ToPascalCase(name_)),
        expression_(new TemplateConstant(latency)) {}
  // This constructor is used when the destination operand latency is specified
  // as '*' - meaning that it will be computed at the time of decode.
  explicit DestinationOperand(std::string name)
      : name_(std::move(name)),
        pascal_case_name_(ToPascalCase(name_)),
        expression_(nullptr) {}
  ~DestinationOperand() { delete expression_; }

  const std::string &name() const { return name_; }
  const std::string &pascal_case_name() const { return pascal_case_name_; }
  TemplateExpression *expression() const { return expression_; }
  bool HasLatency() const { return expression_ != nullptr; }
  absl::StatusOr<int> GetLatency() const {
    if (expression_ == nullptr) return -1;
    auto res = expression_->GetValue();
    if (!res.ok()) {
      return absl::InternalError(absl::StrCat(
          "Template expression evaluation error", res.status().message()));
    }
    auto variant_value = res.value();
    auto *value_ptr = std::get_if<int>(&variant_value);
    if (value_ptr == nullptr) {
      return absl::InternalError("Template expression type error");
    }
    return *value_ptr;
  }

 private:
  std::string name_;
  std::string pascal_case_name_;
  TemplateExpression *expression_;
};

// This struct is used to specify the location of an operand within an
// instruction. It specifies which instruction (or child instruction) number. In
// this case, 0 is the top level instruction, 1 is the first child instruction
// etc. The type is 'p' for predicate operand, 's' for source operand, and 'd'
// for destination operand. The instance number specifies the entry index in the
// source or destination operand vector.
struct OperandLocator {
  int op_spec_number;
  char type;
  int instance;
  OperandLocator(int op_spec_number_, char type_, int instance_)
      : op_spec_number(op_spec_number_), type(type_), instance(instance_) {}
};

struct FormatInfo {
  FormatInfo() = default;
  // Use default copy constructor.
  FormatInfo(const FormatInfo &) = default;
  std::string op_name;
  bool is_formatted = true;
  std::string number_format;
  bool use_address = false;
  std::string operation;
  bool do_left_shift = false;
  int shift_amount = 0;
};

struct DisasmFormat {
  DisasmFormat() = default;
  // Copy constructor.
  DisasmFormat(const DisasmFormat &df) {
    width = df.width;
    for (auto const &frag : df.format_fragment_vec) {
      format_fragment_vec.push_back(frag);
    }
    for (auto const *info : df.format_info_vec) {
      format_info_vec.push_back(new FormatInfo(*info));
    }
  }
  // Destructor.
  ~DisasmFormat() {
    for (auto *info : format_info_vec) {
      delete info;
    }
    format_info_vec.clear();
  }
  int width = 0;
  std::vector<std::string> format_fragment_vec;
  std::vector<FormatInfo *> format_info_vec;
};

struct ResourceReference {
  Resource *resource;
  DestinationOperand *dest_op;
  TemplateExpression *begin_expression;
  TemplateExpression *end_expression;
  ResourceReference(Resource *resource_, DestinationOperand *dest_op_,
                    TemplateExpression *begin_expr_,
                    TemplateExpression *end_expr_)
      : resource(resource_),
        dest_op(dest_op_),
        begin_expression(begin_expr_),
        end_expression(end_expr_) {}
  ResourceReference(const ResourceReference &) = default;
};

using OpLocatorMap = absl::flat_hash_map<std::string, OperandLocator>;

class Opcode {
  friend class OpcodeFactory;

 public:
  // Constructor is private (defined below), only used by OpcodeFactory.
  virtual ~Opcode();

  // Each opcode specifies an optional predicate operand name, an optional list
  // of source operand names, and an optional list of destination operand names.
  // These methods append the source and destination operand names to the
  // opcode. These names are used to create interface methods that are called
  // to get the Predicate, Source and Destination operand interfaces (defined
  // in .../sim/generic/operand_interfaces.h. The implementation of these
  // methods will be left to the user of this generator tool.
  void AppendSourceOpName(absl::string_view op_name);
  void AppendDestOp(absl::string_view op_name, TemplateExpression *expression);
  void AppendDestOp(absl::string_view op_name);
  DestinationOperand *GetDestOp(absl::string_view op_name);
  // Append child opcode specification.
  void AppendChild(Opcode *op) { child_ = op; }
  // Checks destination latencies with the given function. Returns true if all
  // comply.
  bool ValidateDestLatencies(const std::function<bool(int)> &validator) const;
  int instruction_size() const { return instruction_size_; }
  void set_instruction_size(int val) { instruction_size_ = val; }
  Opcode *child() const { return child_; }
  Opcode *parent() const { return parent_; }
  const std::string &name() const { return name_; }
  const std::string &pascal_name() const { return pascal_name_; }
  // Each opcode is assigned a unique value that is used in the slot class
  // enum definition.
  int value() const { return value_; }
  // Predicate, source and destination operand names.
  const std::string &predicate_op_name() const { return predicate_op_name_; }
  void set_predicate_op_name(absl::string_view op_name) {
    predicate_op_name_ = op_name;
  }
  const std::vector<std::string> &source_op_name_vec() const {
    return source_op_name_vec_;
  }
  const std::vector<DestinationOperand *> &dest_op_vec() const {
    return dest_op_vec_;
  }

  OpLocatorMap &op_locator_map() { return op_locator_map_; }  // not const.
  const OpLocatorMap &op_locator_map() const { return op_locator_map_; }

 private:
  Opcode(absl::string_view name, int value);
  int instruction_size_;
  Opcode *child_ = nullptr;
  Opcode *parent_ = nullptr;
  std::string predicate_op_name_;
  std::vector<std::string> source_op_name_vec_;
  std::vector<DestinationOperand *> dest_op_vec_;
  absl::flat_hash_map<std::string, DestinationOperand *> dest_op_map_;
  std::string name_;
  std::string pascal_name_;
  std::string semfunc_code_string_;
  int value_;
  OpLocatorMap op_locator_map_;
};

class OpcodeFactory {
 public:
  OpcodeFactory() = default;
  ~OpcodeFactory() = default;

  // If the opcode doesn't yet exist, create a new opcode and return the
  // pointer, otherwise return an error code.
  absl::StatusOr<Opcode *> CreateOpcode(absl::string_view name);
  Opcode *CreateDefaultOpcode();
  absl::StatusOr<Opcode *> CreateChildOpcode(Opcode *opcode) const;
  // Duplicate the opcode, but evaluate the destination latency expressions
  // with the template argument expression vector.
  absl::StatusOr<Opcode *> CreateDerivedOpcode(const Opcode *opcode,
                                               TemplateInstantiationArgs *args);
  const std::vector<Opcode *> &opcode_vec() const { return opcode_vec_; }

 private:
  absl::btree_set<std::string> opcode_names_;
  std::vector<Opcode *> opcode_vec_;
  int opcode_value_ = 1;
};

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

#endif  // MPACT_SIM_DECODER_OPCODE_H_
