// 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
//
//     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 "sim/renode/kelvin_renode.h"

#include <cstddef>
#include <cstdint>
#include <cstring>
#include <string>

#include "sim/kelvin_top.h"
#include "sim/renode/kelvin_renode_register_info.h"
#include "sim/renode/renode_debug_interface.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "riscv/riscv_debug_info.h"
#include "mpact/sim/generic/core_debug_interface.h"
#include "mpact/sim/generic/data_buffer.h"
#include "mpact/sim/generic/instruction.h"

kelvin::sim::renode::RenodeDebugInterface* CreateKelvinSim(std::string name) {
  auto* top = new kelvin::sim::KelvinRenode(name);
  return top;
}

kelvin::sim::renode::RenodeDebugInterface* CreateKelvinSim(
    std::string name, uint64_t memory_block_size_bytes,
    uint64_t memory_size_bytes, uint8_t** block_ptr_list) {
  auto* top = new kelvin::sim::KelvinRenode(name, memory_block_size_bytes,
                                            memory_size_bytes, block_ptr_list);
  return top;
}

namespace kelvin::sim {

using HaltReasonValueType =
    mpact::sim::generic::CoreDebugInterface::HaltReasonValueType;
using RunStatus = mpact::sim::generic::CoreDebugInterface::RunStatus;
using Instruction = mpact::sim::generic::Instruction;
using RiscVDebugInfo = mpact::sim::riscv::RiscVDebugInfo;

KelvinRenode::KelvinRenode(std::string name) {
  kelvin_top_ = new KelvinTop(name);
}

KelvinRenode::KelvinRenode(std::string name, uint64_t memory_block_size_bytes,
                           uint64_t memory_size_bytes,
                           uint8_t** block_ptr_list) {
  kelvin_top_ = new KelvinTop(name, memory_block_size_bytes, memory_size_bytes,
                              block_ptr_list);
}

KelvinRenode::~KelvinRenode() { delete kelvin_top_; }

absl::Status KelvinRenode::Halt() { return kelvin_top_->Halt(); }
absl::Status KelvinRenode::Halt(HaltReason halt_reason) {
  return kelvin_top_->Halt(halt_reason);
}
absl::Status KelvinRenode::Halt(HaltReasonValueType halt_reason) {
  return kelvin_top_->Halt(halt_reason);
}
absl::StatusOr<int> KelvinRenode::Step(int num_steps) {
  return kelvin_top_->Step(num_steps);
}
absl::Status KelvinRenode::Run() { return kelvin_top_->Run(); }
absl::Status KelvinRenode::Wait() { return kelvin_top_->Wait(); }
absl::StatusOr<RunStatus> KelvinRenode::GetRunStatus() {
  return kelvin_top_->GetRunStatus();
}
absl::StatusOr<HaltReasonValueType> KelvinRenode::GetLastHaltReason() {
  return kelvin_top_->GetLastHaltReason();
}

absl::StatusOr<uint64_t> KelvinRenode::ReadRegister(const std::string& name) {
  return kelvin_top_->ReadRegister(name);
}

absl::Status KelvinRenode::WriteRegister(const std::string& name,
                                         uint64_t value) {
  return kelvin_top_->WriteRegister(name, value);
}

absl::StatusOr<size_t> KelvinRenode::ReadMemory(uint64_t address, void* buf,
                                                size_t length) {
  return kelvin_top_->ReadMemory(address, buf, length);
}

absl::StatusOr<size_t> KelvinRenode::WriteMemory(uint64_t address,
                                                 const void* buf,
                                                 size_t length) {
  return kelvin_top_->WriteMemory(address, buf, length);
}

absl::StatusOr<mpact::sim::generic::DataBuffer*>
KelvinRenode::GetRegisterDataBuffer(const std::string& name) {
  return kelvin_top_->GetRegisterDataBuffer(name);
}

bool KelvinRenode::HasBreakpoint(uint64_t address) {
  return kelvin_top_->HasBreakpoint(address);
}

absl::Status KelvinRenode::SetSwBreakpoint(uint64_t address) {
  return kelvin_top_->SetSwBreakpoint(address);
}

absl::Status KelvinRenode::ClearSwBreakpoint(uint64_t address) {
  return kelvin_top_->ClearSwBreakpoint(address);
}

absl::Status KelvinRenode::ClearAllSwBreakpoints() {
  return kelvin_top_->ClearAllSwBreakpoints();
}

absl::StatusOr<mpact::sim::generic::Instruction*> KelvinRenode::GetInstruction(
    uint64_t address) {
  return kelvin_top_->GetInstruction(address);
}

absl::StatusOr<std::string> KelvinRenode::GetDisassembly(uint64_t address) {
  return kelvin_top_->GetDisassembly(address);
}

absl::Status KelvinRenode::LoadImage(const std::string& image_path,
                                     uint64_t start_address) {
  return kelvin_top_->LoadImage(image_path, start_address);
}

absl::StatusOr<uint64_t> KelvinRenode::ReadRegister(uint32_t reg_id) {
  auto ptr = RiscVDebugInfo::Instance()->debug_register_map().find(reg_id);
  if (ptr == RiscVDebugInfo::Instance()->debug_register_map().end()) {
    return absl::NotFoundError(
        absl::StrCat("Not found reg id: ", absl::Hex(reg_id)));
  }

  return ReadRegister(ptr->second);
}

absl::Status KelvinRenode::WriteRegister(uint32_t reg_id, uint64_t value) {
  auto ptr = RiscVDebugInfo::Instance()->debug_register_map().find(reg_id);
  if (ptr == RiscVDebugInfo::Instance()->debug_register_map().end()) {
    return absl::NotFoundError(
        absl::StrCat("Not found reg id: ", absl::Hex(reg_id)));
  }

  return WriteRegister(ptr->second, value);
}

int32_t KelvinRenode::GetRenodeRegisterInfoSize() const {
  return KelvinRenodeRegisterInfo::GetRenodeRegisterInfo().size();
}

absl::Status KelvinRenode::GetRenodeRegisterInfo(int32_t index, int32_t max_len,
                                                 char* name,
                                                 RenodeCpuRegister& info) {
  auto const& register_info = KelvinRenodeRegisterInfo::GetRenodeRegisterInfo();
  if ((index < 0 || index >= register_info.size())) {
    return absl::OutOfRangeError(
        absl::StrCat("Register info index (", index, ") out of range"));
  }
  info = register_info[index];
  auto const& reg_map = RiscVDebugInfo::Instance()->debug_register_map();
  auto ptr = reg_map.find(info.index);
  if (ptr == reg_map.end()) {
    name[0] = '\0';
  } else {
    strncpy(name, ptr->second.c_str(), max_len);
  }

  return absl::OkStatus();
}

}  // namespace kelvin::sim
