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

#include <cstddef>
#include <cstdint>

#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "googlemock/include/gmock/gmock.h"
#include "googletest/include/gtest/gtest.h"
#include "mpact/sim/generic/arch_state.h"
#include "mpact/sim/generic/complex_resource.h"
#include "mpact/sim/generic/operand_interface.h"

namespace {

using ::mpact::sim::generic::ArchState;
using ::mpact::sim::generic::ComplexResource;
using ::mpact::sim::generic::ComplexResourceOperand;
using ::mpact::sim::generic::SourceOperandInterface;

constexpr size_t kCycleDepth = 234;
constexpr size_t kLow = 100;
constexpr size_t kHigh = 107;
constexpr char kResourceName[] = "my_resource";
constexpr char kArchName[] = "test_architecture";

// Bits 100-107 are cleared in this bit vector.
constexpr uint64_t kFree100To107[] = {
    0xffff'ffff'ffff'ffff, 0xffff'f00f'ffff'ffff, 0xffff'ffff'ffff'ffff,
    0xffff'ffff'ffc0'0000};

// Longer than what is supported.
constexpr uint64_t kTooLong[5] = {0xffff, 0, 0, 0, 0};
// Longer than 234 bits.
constexpr uint64_t kOnesTooFar[4] = {0, 0, 0, 0xffff'ffff'fff0'0000};
// All zeros, no cycle is reserved.
constexpr uint64_t kAllZeros[4] = {0};
// The request vector corresponding to kFree100To107
constexpr uint64_t kAcquire100To107[] = {
    ~kFree100To107[0], ~kFree100To107[1], ~kFree100To107[2],
    ~kFree100To107[3] & 0xffff'ffff'ffc0'0000};

// ArchState derived class that is passed in to the resource (so that it can
// access the clock.
class MockArchState : public ArchState {
 public:
  MockArchState(absl::string_view id, SourceOperandInterface* pc_op)
      : ArchState(id, pc_op) {}
  explicit MockArchState(absl::string_view id) : MockArchState(id, nullptr) {}
  void set_cycle(uint64_t value) { ArchState::set_cycle(value); }
};

// Test fixture. Instantiates and deletes instances of MockArchState and the
// ComplexResource and ComplexResourceOperand.
class ComplexResourceOperandTest : public testing::Test {
 protected:
  ComplexResourceOperandTest() {
    arch_state_ = new MockArchState(kArchName);
    resource_ = new ComplexResource(arch_state_, kResourceName, kCycleDepth);
    operand_ = new ComplexResourceOperand(resource_);
  }

  ~ComplexResourceOperandTest() override {
    delete operand_;
    delete resource_;
    delete arch_state_;
  }

  MockArchState* arch_state_;
  ComplexResource* resource_;
  ComplexResourceOperand* operand_;
};

// Create and check name.
TEST_F(ComplexResourceOperandTest, Create) {
  EXPECT_EQ(operand_->AsString(), resource_->name());
}

// Check error status from setting the cycle mask.
TEST_F(ComplexResourceOperandTest, CycleMask) {
  auto* op = new ComplexResourceOperand(nullptr);
  EXPECT_TRUE(absl::IsInternal(op->SetCycleMask(kLow, kHigh)));
  EXPECT_TRUE(absl::IsInvalidArgument(operand_->SetCycleMask(kHigh, kLow)));
  EXPECT_TRUE(
      absl::IsInvalidArgument(operand_->SetCycleMask(kLow, kCycleDepth)));
  EXPECT_TRUE(operand_->SetCycleMask(kLow, kHigh).ok());
  EXPECT_THAT(
      operand_->bit_array(),
      testing::ElementsAreArray(absl::MakeSpan(kAcquire100To107)
                                    .first(operand_->bit_array().size())));
  // Now try setting using arrays.
  EXPECT_TRUE(absl::IsInternal(op->SetCycleMask(kAcquire100To107)));
  EXPECT_TRUE(absl::IsInvalidArgument(operand_->SetCycleMask(kTooLong)));
  EXPECT_TRUE(absl::IsInvalidArgument(operand_->SetCycleMask(kOnesTooFar)));
  EXPECT_TRUE(absl::IsInvalidArgument(operand_->SetCycleMask(kAllZeros)));
  EXPECT_TRUE(operand_->SetCycleMask(kAcquire100To107).ok());
  delete op;
}

// Test IsFree function.
TEST_F(ComplexResourceOperandTest, IsFree) {
  // First set the resource to be busy except for cycles 100..107.
  resource_->Acquire(kFree100To107);
  // Initialize the cycle mask in the operand.
  EXPECT_TRUE(operand_->SetCycleMask(kLow, kHigh).ok());
  // Verify the bit array in the resource.
  EXPECT_THAT(resource_->bit_array(), testing::ElementsAreArray(kFree100To107));
  EXPECT_TRUE(operand_->IsFree());

  // Set the operand mask using the array itself.
  EXPECT_TRUE(operand_->SetCycleMask(kAcquire100To107).ok());
  EXPECT_THAT(operand_->bit_array(),
              testing::ElementsAreArray(kAcquire100To107));
  EXPECT_TRUE(operand_->IsFree());
  // Advance the cycle count (which shifts the resource bit vector at the next
  // call).
  arch_state_->set_cycle(1);
  // The call should fail now as a "busy" cycle has been shifted into the
  // request window.
  EXPECT_FALSE(operand_->IsFree());
}

// Test Acquire
TEST_F(ComplexResourceOperandTest, Acquire) {
  EXPECT_TRUE(operand_->SetCycleMask(kLow, kHigh).ok());
  operand_->Acquire();
  // Verify that the resource was acquired for the right cycles.
  EXPECT_THAT(resource_->bit_array(),
              testing::ElementsAreArray(kAcquire100To107));
}

}  // namespace
