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

#include "mpact/sim/decoder/opcode.h"

#include <memory>
#include <string>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "googlemock/include/gmock/gmock.h"  // IWYU pragma: keep
#include "googletest/include/gtest/gtest.h"
#include "mpact/sim/decoder/instruction_set.h"

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

constexpr char kInstructionSetName[] = "Test";
constexpr char kOpcodeName0[] = "opcode_0";
constexpr char kOpcodeName1[] = "opcode_1";
constexpr char kOpcodeName2[] = "opcode_2";
constexpr char kPredicateOpName[] = "pred";

const char* kOpcodeNames[] = {kOpcodeName0, kOpcodeName1, kOpcodeName2};

// Test fixture for opcode test.
class OpcodeTest : public testing::Test {
 protected:
  OpcodeTest() {
    instruction_set_ = std::make_unique<InstructionSet>(kInstructionSetName);

    absl::StatusOr<Opcode*> result =
        instruction_set_->opcode_factory()->CreateOpcode(kOpcodeName0);
    opcode_ = result.ok() ? result.value() : nullptr;
  }

  ~OpcodeTest() override { delete opcode_; }

  std::unique_ptr<InstructionSet> instruction_set_;
  Opcode* opcode_;  // Does not have to be deleted, as OpcodeFactory handles it.
};

TEST_F(OpcodeTest, Basic) {
  EXPECT_STREQ(opcode_->name().c_str(), kOpcodeName0);
  EXPECT_EQ(opcode_->value(), 1);
  EXPECT_STREQ(opcode_->predicate_op_name().c_str(), "");
  EXPECT_EQ(opcode_->source_op_vec().size(), 0);
  EXPECT_EQ(opcode_->dest_op_vec().size(), 0);
}

// Verify that values of opcodes increment as you create new ones.
TEST_F(OpcodeTest, Multiple) {
  // Creating a duplicate opcode should fail.
  absl::StatusOr<Opcode*> result =
      instruction_set_->opcode_factory()->CreateOpcode(kOpcodeNames[0]);
  EXPECT_TRUE(absl::IsInternal(result.status()));
  for (int indx = 1; indx < 3; indx++) {
    result =
        instruction_set_->opcode_factory()->CreateOpcode(kOpcodeNames[indx]);
    // Since one opcode is created in fixture, these opcode values start at 2.
    ASSERT_TRUE(result.ok());
    Opcode* opcode = result.value();
    EXPECT_EQ(opcode->value(), indx + 1);
    delete opcode;
  }
}

// Verify setter for predicate operand name.
TEST_F(OpcodeTest, PredicateOperandName) {
  opcode_->set_predicate_op_name(kPredicateOpName);
  EXPECT_STREQ(opcode_->predicate_op_name().c_str(), kPredicateOpName);
}

// Verify source operand name vector.
TEST_F(OpcodeTest, SourceOperandNames) {
  for (int indx = 0; indx < 3; indx++) {
    std::string source_op_name = absl::StrCat("SourceOp", indx);
    opcode_->AppendSourceOp(source_op_name, /*is_array=*/false,
                            /*is_reloc=*/false);
    EXPECT_EQ(opcode_->source_op_vec().size(), indx + 1);
    EXPECT_STREQ(opcode_->source_op_vec()[indx].name.c_str(),
                 source_op_name.c_str());
  }
}

// Verify destination operand name vector.
TEST_F(OpcodeTest, DestOperandNames) {
  for (int indx = 0; indx < 2; indx++) {
    std::string dest_op_name = absl::StrCat("DestOp", indx);
    if (indx == 0) {
      opcode_->AppendDestOp(dest_op_name, /*is_array=*/false,
                            /*is_reloc=*/false);
    } else if (indx == 1) {
      // Using nullptr - the value isn't checked upon append.
      opcode_->AppendDestOp(dest_op_name, /*is_array=*/false,
                            /*is_reloc=*/false, nullptr);
    }
    EXPECT_EQ(opcode_->dest_op_vec().size(), indx + 1);
    EXPECT_STREQ(opcode_->dest_op_vec()[indx]->name().c_str(),
                 dest_op_name.c_str());
  }
}

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