// 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/bundle.h"

#include <cstddef>
#include <memory>
#include <vector>

#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 kBundleName[] = "TestBundle";

constexpr char kSubBundleName0[] = "TestSubBundle0";
constexpr char kSubBundleName1[] = "TestSubBundle1";
constexpr char kSubBundleName2[] = "TestSubBundle2";
const char *kSubBundleNames[3] = {kSubBundleName0, kSubBundleName1,
                                  kSubBundleName2};
constexpr char kSlotName0[] = "TestSlot0";
constexpr char kSlotName1[] = "TestSlot1";
constexpr char kSlotName2[] = "TestSlot2";
const char *kSlotNames[3] = {kSlotName0, kSlotName1, kSlotName2};

class BundleTest : public testing::Test {
 protected:
  BundleTest() {
    instruction_set_ = std::make_unique<InstructionSet>(kInstructionSetName);
    bundle_ =
        std::make_unique<Bundle>(kBundleName, instruction_set_.get(), nullptr);
  }

  ~BundleTest() override {};

  std::unique_ptr<InstructionSet> instruction_set_;
  std::unique_ptr<Bundle> bundle_;
};

// Verify basic initial settings.
TEST_F(BundleTest, Basic) {
  EXPECT_STREQ(bundle_->name().c_str(), kBundleName);
  EXPECT_EQ(bundle_->bundle_names().size(), 0);
  EXPECT_EQ(bundle_->slot_uses().size(), 0);
  EXPECT_EQ(bundle_->instruction_set(), instruction_set_.get());
  EXPECT_FALSE(bundle_->is_marked());
}

// Verify setter for is marked.
TEST_F(BundleTest, IsMarked) {
  bundle_->set_is_marked(true);
  EXPECT_TRUE(bundle_->is_marked());
  bundle_->set_is_marked(false);
  EXPECT_FALSE(bundle_->is_marked());
}

// Verify that sub-bundle names work.
TEST_F(BundleTest, SubBundle) {
  for (int index = 0; index < 3; index++) {
    EXPECT_EQ(bundle_->bundle_names().size(), index);
    bundle_->AppendBundleName(kSubBundleNames[index]);
    EXPECT_EQ(bundle_->bundle_names().size(), index + 1);
    EXPECT_STREQ(bundle_->bundle_names()[index].c_str(),
                 kSubBundleNames[index]);
  }
}

// Verify slot uses is correct.
TEST_F(BundleTest, Slots) {
  // Vector of slot instances used.
  std::vector<std::vector<int>> slot_vec = {{0}, {1, 3}, {0, 2, 4}};
  for (int index = 0; index < 3; index++) {
    EXPECT_EQ(bundle_->slot_uses().size(), index);
    bundle_->AppendSlot(kSlotNames[index], slot_vec[index]);
    EXPECT_EQ(bundle_->slot_uses().size(), index + 1);
    EXPECT_STREQ(bundle_->slot_uses()[index].first.c_str(), kSlotNames[index]);
    EXPECT_EQ(bundle_->slot_uses()[index].second.size(),
              slot_vec[index].size());
    for (size_t vec_indx = 0; vec_indx < slot_vec[index].size(); vec_indx++) {
      EXPECT_EQ(bundle_->slot_uses()[index].second[vec_indx],
                slot_vec[index][vec_indx]);
    }
  }
}

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