// 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 "absl/status/status.h"
#include "googlemock/include/gmock/gmock.h"
#include "googletest/include/gtest/gtest.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
