// 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 <any>
#include <cstdint>
#include <memory>

#include "absl/strings/string_view.h"
#include "absl/types/any.h"
#include "googlemock/include/gmock/gmock.h"
#include "googletest/include/gtest/gtest.h"
#include "mpact/sim/generic/arch_state.h"
#include "mpact/sim/generic/data_buffer.h"
#include "mpact/sim/generic/delay_line.h"
#include "mpact/sim/generic/fifo.h"
#include "mpact/sim/generic/operand_interface.h"

namespace mpact {
namespace sim {
namespace generic {
namespace {

using ScalarFifo = Fifo<uint32_t>;
using Vector8Fifo = VectorFifo<uint32_t, 8>;

constexpr int kFifoCapacity = 3;

// Define a class that derives from ArchState since constructors are
// protected.
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) {}
};

// Test fixture to keep a single copy of registers, delay line and
// DataBufferFactory.
class FifoOperandTest : public testing::Test {
 protected:
  FifoOperandTest() {
    arch_state_ = new MockArchState("MockArchState");
    sfifo_ = new ScalarFifo(arch_state_, "S0", kFifoCapacity);
    vfifo_ = new Vector8Fifo(arch_state_, "V0", kFifoCapacity);
  }

  ~FifoOperandTest() override {
    delete vfifo_;
    delete sfifo_;
    delete arch_state_;
  }

  MockArchState *arch_state_;
  ScalarFifo *sfifo_;
  Vector8Fifo *vfifo_;
};

// Tests that the fifo source operands are initialized correctly.
TEST_F(FifoOperandTest, SourceOperandInitialization) {
  auto s_src_op = std::make_unique<FifoSourceOperand<uint32_t>>(sfifo_);
  EXPECT_EQ(std::any_cast<FifoBase *>(s_src_op->GetObject()),
            static_cast<FifoBase *>(sfifo_));
  EXPECT_EQ(s_src_op->shape(), sfifo_->shape());

  auto v_src_op = std::make_unique<FifoSourceOperand<uint32_t>>(vfifo_);
  EXPECT_EQ(std::any_cast<FifoBase *>(v_src_op->GetObject()),
            static_cast<FifoBase *>(vfifo_));
  EXPECT_EQ(v_src_op->shape(), vfifo_->shape());
}

// Tests that the fifo destination operands are initialized correctly.
TEST_F(FifoOperandTest, DestinationOperandInitialization) {
  auto s_dst_op = std::make_unique<FifoDestinationOperand<uint32_t>>(sfifo_, 1);
  EXPECT_EQ(s_dst_op->latency(), 1);
  EXPECT_EQ(s_dst_op->shape(), sfifo_->shape());

  auto v_dst_op = std::make_unique<FifoDestinationOperand<uint32_t>>(vfifo_, 4);
  EXPECT_EQ(v_dst_op->latency(), 4);
  EXPECT_EQ(v_dst_op->shape(), vfifo_->shape());
}

// Tests that a destination fifo operand can update a fifo so that
// it is visible in a source fifo operand.
TEST_F(FifoOperandTest, ScalarFifoValueWriteAndRead) {
  auto dst_op = sfifo_->CreateDestinationOperand(1);
  auto src_op = sfifo_->CreateSourceOperand();

  // Get DataBuffer from destination operand and initialize the value.
  DataBuffer *db = dst_op->AllocateDataBuffer();
  db->Set<uint32_t>(0, 0xDEADBEEF);

  // Submit data buffer and advance the delay line by the 1 cycle latency.
  db->Submit();
  arch_state_->AdvanceDelayLines();

  // Verify that the source operand can read the new value.
  EXPECT_EQ(src_op->AsUint32(0), 0xDEADBEEF);

  // Get a new data buffer and initialize it to zero.
  DataBuffer *db2 = dst_op->AllocateDataBuffer();
  db2->Set<uint32_t>(0, 0);

  // Submit the data buffer and advance the delay line 1 cycle.
  db2->Submit();
  arch_state_->AdvanceDelayLines();

  // Verify the fifo still has the old value (hasn't been pop'ed).
  EXPECT_EQ(src_op->AsUint32(0), 0xDEADBEEF);

  // Pop the fifo and verify the new value is there.
  std::any_cast<FifoBase *>(src_op->GetObject())->Pop();
  EXPECT_EQ(src_op->AsUint32(0), 0);

  delete dst_op;
  delete src_op;
}

// Tests that a destination vector register operand can update a register so
// that it is visible in a source register operand.
TEST_F(FifoOperandTest, VectorFifoValueWriteAndRead) {
  auto dst_op = vfifo_->CreateDestinationOperand(2);
  auto src_op = vfifo_->CreateSourceOperand();

  // Get DataBuffer from destination operand and initialize the value.
  DataBuffer *db = dst_op->AllocateDataBuffer();
  for (int index = 0; index < vfifo_->shape()[0]; index++) {
    db->Set<uint32_t>(index, 0xDEAD0000 | index);
  }

  // Submit the data buffer and advance the delay line by the 2 cycle latency.
  db->Submit();
  arch_state_->AdvanceDelayLines();
  arch_state_->AdvanceDelayLines();

  // Verify that the value has been written correctly to the register.
  for (int index = 0; index < vfifo_->shape()[0]; index++) {
    EXPECT_EQ(src_op->AsUint32(index), 0xDEAD0000 | index);
  }

  // Get another DataBuffer from destination operand and initialize to zeros.
  DataBuffer *db2 = dst_op->AllocateDataBuffer();
  for (int index = 0; index < vfifo_->shape()[0]; index++) {
    db2->Set<uint32_t>(index, 0);
  }

  // Submit the data buffer and advance the delay line by the 2 cycle latency.
  db2->Submit();
  arch_state_->AdvanceDelayLines();
  arch_state_->AdvanceDelayLines();

  // Verify that the value is the same as before (fifo hasn't been pop'ed).
  for (int index = 0; index < vfifo_->shape()[0]; index++) {
    EXPECT_EQ(src_op->AsUint32(index), 0xDEAD0000 | index);
  }

  // Pop the fifo and verify that the value has been updated.
  std::any_cast<FifoBase *>(src_op->GetObject())->Pop();
  for (int index = 0; index < vfifo_->shape()[0]; index++) {
    EXPECT_EQ(src_op->AsUint32(index), 0);
  }

  delete dst_op;
  delete src_op;
}

}  // namespace
}  // namespace generic
}  // namespace sim
}  // namespace mpact
