// Copyright 2024 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
//
//     http://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 "cheriot/cheriot_state.h"

#include <cstdint>
#include <iostream>
#include <string>

#include "absl/log/check.h"
#include "absl/strings/str_format.h"
#include "cheriot/cheriot_register.h"
#include "googlemock/include/gmock/gmock.h"
#include "mpact/sim/generic/instruction.h"
#include "mpact/sim/util/memory/tagged_flat_demand_memory.h"
#include "riscv//riscv_state.h"

namespace {

using ::mpact::sim::cheriot::CheriotRegister;
using ::mpact::sim::cheriot::CheriotState;
using RVEC = ::mpact::sim::riscv::ExceptionCode;

constexpr int kPcValue = 0x1000;
constexpr int kMemAddr = 0x1200;
constexpr uint32_t kMemValue = 0xdeadbeef;

// Only limited testing of the CheriotState class for now as it has limited
// additional functionality over the ArchState class.

TEST(CheriotStateTest, Basic) {
  auto *state = new CheriotState("test");
  // Make sure pc has been created.
  auto iter = state->registers()->find("pcc");
  auto *ptr = (iter != state->registers()->end()) ? iter->second : nullptr;
  CHECK_NE(ptr, nullptr);
  auto *pcc = static_cast<CheriotRegister *>(ptr);
  // Make pcc an executable root.
  pcc->CopyFrom(*state->executable_root());
  // Set pc to 0x1000, then read value back through pc operand.
  pcc->data_buffer()->Set<uint32_t>(0, kPcValue);
  auto *pc_op = state->pc_operand();
  EXPECT_EQ(pc_op->AsUint32(0), kPcValue);
  delete state;
}

TEST(CheriotStateTest, Memory) {
  auto *state = new CheriotState("test");
  auto *db = state->db_factory()->Allocate<uint32_t>(1);
  state->LoadMemory(nullptr, kMemAddr, db, nullptr, nullptr);
  EXPECT_EQ(db->Get<uint32_t>(0), 0);
  db->Set<uint32_t>(0, kMemValue);
  state->StoreMemory(nullptr, kMemAddr, db);
  db->Set<uint32_t>(0, 0);
  state->LoadMemory(nullptr, kMemAddr, db, nullptr, nullptr);
  EXPECT_EQ(db->Get<uint32_t>(0), kMemValue);
  db->DecRef();
  delete state;
}

TEST(CheriotStateTest, OutOfBoundLoad) {
  auto *state = new CheriotState("test");
  state->set_max_physical_address(kMemAddr - 4);
  state->set_on_trap([](bool is_interrupt, uint64_t trap_value,
                        uint64_t exception_code, uint64_t epc,
                        const mpact::sim::riscv::Instruction *inst) -> bool {
    if (exception_code ==
        static_cast<uint64_t>(
            mpact::sim::riscv::ExceptionCode::kLoadAccessFault)) {
      std::cerr << "Load Access Fault" << std::endl;
      return true;
    }
    return false;
  });
  auto *db = state->db_factory()->Allocate<uint32_t>(1);
  // Create a dummy instruction so trap can dereference the address.
  auto *dummy_inst = new mpact::sim::generic::Instruction(0x0, nullptr);
  dummy_inst->set_size(4);
  testing::internal::CaptureStderr();
  state->LoadMemory(dummy_inst, kMemAddr, db, nullptr, nullptr);
  const std::string stderr = testing::internal::GetCapturedStderr();
  EXPECT_THAT(stderr, testing::HasSubstr("Load Access Fault"));
  db->DecRef();
  dummy_inst->DecRef();
  delete state;
}

// Verify that the mshwm register decrements by 16.
TEST(CheriotStateTest, Mshwm) {
  auto *mem = new mpact::sim::util::TaggedFlatDemandMemory(8);
  auto *state = new CheriotState("test", mem);
  auto *byte_db = state->db_factory()->Allocate<uint8_t>(1);
  auto mshwmb_res = state->csr_set()->GetCsr("mshwmb");
  CHECK_OK(mshwmb_res);
  auto *mshwmb = mshwmb_res.value();
  auto mshwm_res = state->csr_set()->GetCsr("mshwm");
  CHECK_OK(mshwm_res);
  auto *mshwm = mshwm_res.value();
  mshwmb->Write(0x0U);
  mshwm->Write(0x80000000);
  state->StoreMemory(nullptr, 0x7fff'ffff, byte_db);
  EXPECT_EQ(mshwm->AsUint32(), 0x7fff'fff0) << absl::StrFormat(
      "mshwm == 0x%08x != 0x%08x", mshwm->AsUint32(), 0x7fff'fff0);
  EXPECT_EQ(mshwmb->AsUint32(), 0x0);
  byte_db->DecRef();
  delete state;
  delete mem;
}

}  // namespace
