#include "riscv/riscv_zicond_instructions.h"

#include <cstdint>
#include <string>
#include <tuple>
#include <vector>

#include "absl/container/flat_hash_map.h"
#include "absl/log/check.h"
#include "absl/strings/string_view.h"
#include "googlemock/include/gmock/gmock.h"
#include "mpact/sim/generic/arch_state.h"
#include "mpact/sim/generic/data_buffer.h"
#include "mpact/sim/generic/instruction.h"
#include "riscv/riscv_register.h"

namespace {

using ::mpact::sim::generic::ArchState;
using ::mpact::sim::generic::Instruction;
using ::mpact::sim::riscv::RV32Register;
using ::mpact::sim::riscv::RV64Register;

constexpr uint32_t kInstAddress = 0x2468;
constexpr char kX1[] = "x1";
constexpr char kX2[] = "x2";
constexpr char kX3[] = "x3";
constexpr uint32_t kVal1 = 0x12345678;
constexpr uint32_t kVal2 = 0x87654321;
constexpr uint32_t kVal3 = 0xdeadbeef;

class TestState : public ArchState {
 public:
  TestState() : ArchState("test") {}
};

class RiscVZicondInstructionTest : public testing::Test {
 public:
  RiscVZicondInstructionTest() {
    instruction_ = new Instruction(kInstAddress, &state_);
    instruction_->set_size(4);
    for (auto reg_name : {kX1, kX2, kX3}) {
      rv32_regs_.insert({reg_name, new RV32Register(&state_, reg_name)});
      rv64_regs_.insert({reg_name, new RV64Register(&state_, reg_name)});
    }
  }

  ~RiscVZicondInstructionTest() override {
    delete instruction_;
    for (auto reg : rv32_regs_) delete reg.second;
    for (auto reg : rv64_regs_) delete reg.second;
  }

  // Initializes the semantic function of the instruction object.
  void SetSemanticFunction(Instruction::SemanticFunction fcn) {
    instruction_->set_semantic_function(fcn);
  }

  // Returns the value of the named register.
  template <typename RegisterType>
  typename RegisterType::ValueType GetRegisterValue(
      absl::string_view reg_name) {
    RegisterType* reg;
    if constexpr (std::is_same_v<RegisterType, RV32Register>) {
      reg = rv32_regs_[reg_name];
    } else {
      reg = rv64_regs_[reg_name];
    }
    CHECK_NE(reg, nullptr);
    return reg->data_buffer()->template Get<typename RegisterType::ValueType>(
        0);
  }

  template <typename RegisterType>
  void AppendRegisterOperands(const std::vector<std::string>& sources,
                              const std::vector<std::string>& destinations) {
    absl::flat_hash_map<std::string, RegisterType*>* regs;
    if constexpr (std::is_same_v<RegisterType, RV32Register>) {
      regs = &rv32_regs_;
    } else {
      regs = &rv64_regs_;
    }
    for (auto src : sources) {
      auto* reg = (*regs)[src];
      CHECK_NE(reg, nullptr);
      instruction_->AppendSource(reg->CreateSourceOperand());
    }
    for (auto dest : destinations) {
      auto* reg = (*regs)[dest];
      CHECK_NE(reg, nullptr);
      instruction_->AppendDestination(reg->CreateDestinationOperand(0));
    }
  }

  template <typename RegisterType>
  void SetRegisterValues(
      const std::vector<
          std::tuple<std::string, typename RegisterType::ValueType>>
          values) {
    absl::flat_hash_map<std::string, RegisterType*>* regs;
    if constexpr (std::is_same_v<RegisterType, RV32Register>) {
      regs = &rv32_regs_;
    } else {
      regs = &rv64_regs_;
    }
    for (auto& [reg_name, value] : values) {
      auto* reg = (*regs)[reg_name];
      CHECK_NE(reg, nullptr);
      auto* db =
          state_.db_factory()->Allocate<typename RegisterType::ValueType>(1);
      db->template Set<typename RegisterType::ValueType>(0, value);
      reg->SetDataBuffer(db);
      db->DecRef();
    }
  }

  Instruction* instruction() { return instruction_; }

 private:
  TestState state_;
  Instruction* instruction_;
  absl::flat_hash_map<std::string, RV32Register*> rv32_regs_;
  absl::flat_hash_map<std::string, RV64Register*> rv64_regs_;
};

TEST_F(RiscVZicondInstructionTest, RV32CzeroEqz) {
  using Reg = RV32Register;
  AppendRegisterOperands<Reg>({kX1, kX2}, {kX3});
  SetSemanticFunction(&::mpact::sim::riscv::RV32::RiscVCzeroEqz);
  SetRegisterValues<Reg>({{kX1, kVal1}, {kX2, kVal2}, {kX3, kVal3}});
  instruction()->Execute(nullptr);
  EXPECT_EQ(GetRegisterValue<Reg>(kX3), kVal1);
  SetRegisterValues<Reg>({{kX1, kVal1}, {kX2, 0}, {kX3, kVal3}});
  instruction()->Execute(nullptr);
  EXPECT_EQ(GetRegisterValue<Reg>(kX3), 0);
}

TEST_F(RiscVZicondInstructionTest, RV32CzeroNez) {
  using Reg = RV32Register;
  AppendRegisterOperands<Reg>({kX1, kX2}, {kX3});
  SetSemanticFunction(&::mpact::sim::riscv::RV32::RiscVCzeroNez);
  SetRegisterValues<Reg>({{kX1, kVal1}, {kX2, 0}, {kX3, kVal3}});
  instruction()->Execute(nullptr);
  EXPECT_EQ(GetRegisterValue<Reg>(kX3), kVal1);
  SetRegisterValues<Reg>({{kX1, kVal1}, {kX2, kVal2}, {kX3, kVal3}});
  instruction()->Execute(nullptr);
  EXPECT_EQ(GetRegisterValue<Reg>(kX3), 0);
}

TEST_F(RiscVZicondInstructionTest, RV64CzeroEqz) {
  using Reg = RV64Register;
  AppendRegisterOperands<Reg>({kX1, kX2}, {kX3});
  SetSemanticFunction(&::mpact::sim::riscv::RV64::RiscVCzeroEqz);
  SetRegisterValues<Reg>({{kX1, kVal1}, {kX2, kVal2}, {kX3, kVal3}});
  instruction()->Execute(nullptr);
  EXPECT_EQ(GetRegisterValue<Reg>(kX3), kVal1);
  SetRegisterValues<Reg>({{kX1, kVal1}, {kX2, 0}, {kX3, kVal3}});
  instruction()->Execute(nullptr);
  EXPECT_EQ(GetRegisterValue<Reg>(kX3), 0);
}

TEST_F(RiscVZicondInstructionTest, RV64CzeroNez) {
  using Reg = RV64Register;
  AppendRegisterOperands<Reg>({kX1, kX2}, {kX3});
  SetSemanticFunction(&::mpact::sim::riscv::RV64::RiscVCzeroNez);
  SetRegisterValues<Reg>({{kX1, kVal1}, {kX2, 0}, {kX3, kVal3}});
  instruction()->Execute(nullptr);
  EXPECT_EQ(GetRegisterValue<Reg>(kX3), kVal1);
  SetRegisterValues<Reg>({{kX1, kVal1}, {kX2, kVal2}, {kX3, kVal3}});
  instruction()->Execute(nullptr);
  EXPECT_EQ(GetRegisterValue<Reg>(kX3), 0);
}

}  // namespace
