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

#include <cstddef>
#include <cstdint>
#include <string>
#include <utility>

#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "cheriot/cheriot_renode_cli_top.h"
#include "cheriot/cheriot_state.h"
#include "mpact/sim/generic/core_debug_interface.h"

namespace mpact {
namespace sim {
namespace cheriot {

using ::mpact::sim::generic::AccessType;
using RunStatus = ::mpact::sim::generic::CoreDebugInterface::RunStatus;
using HaltReasonValueType =
    ::mpact::sim::generic::CoreDebugInterface::HaltReasonValueType;

CheriotCLIForwarder::CheriotCLIForwarder(CheriotRenodeCLITop *cheriot_cli_top)
    : cheriot_cli_top_(cheriot_cli_top) {}

// Forward the calls to the CheriotRenodeCLITop class - CLI methods.

absl::StatusOr<size_t> CheriotCLIForwarder::ReadTagMemory(uint64_t address,
                                                          void *buf,
                                                          size_t length) {
  return cheriot_cli_top_->CLIReadTagMemory(address, buf, length);
}

absl::Status CheriotCLIForwarder::SetDataWatchpoint(uint64_t address,
                                                    size_t length,
                                                    AccessType access_type) {
  return cheriot_cli_top_->CLISetDataWatchpoint(address, length, access_type);
}

absl::Status CheriotCLIForwarder::ClearDataWatchpoint(uint64_t address,
                                                      AccessType access_type) {
  return cheriot_cli_top_->CLIClearDataWatchpoint(address, access_type);
}

absl::StatusOr<int> CheriotCLIForwarder::SetActionPoint(
    uint64_t address, absl::AnyInvocable<void(uint64_t, int)> action) {
  return cheriot_cli_top_->CLISetActionPoint(address, std::move(action));
}

absl::Status CheriotCLIForwarder::ClearActionPoint(uint64_t address, int id) {
  return cheriot_cli_top_->CLIClearActionPoint(address, id);
}

absl::Status CheriotCLIForwarder::EnableAction(uint64_t address, int id) {
  return cheriot_cli_top_->CLIEnableAction(address, id);
}

absl::Status CheriotCLIForwarder::DisableAction(uint64_t address, int id) {
  return cheriot_cli_top_->CLIDisableAction(address, id);
}

void CheriotCLIForwarder::SetBreakOnControlFlowChange(bool value) {
  cheriot_cli_top_->CLISetBreakOnControlFlowChange(value);
}

absl::Status CheriotCLIForwarder::Halt() { return cheriot_cli_top_->CLIHalt(); }

absl::StatusOr<int> CheriotCLIForwarder::Step(int num) {
  return cheriot_cli_top_->CLIStep(num);
}

absl::Status CheriotCLIForwarder::Run() { return cheriot_cli_top_->CLIRun(); }

absl::Status CheriotCLIForwarder::Wait() { return cheriot_cli_top_->CLIWait(); }

// Returns the current run status.
absl::StatusOr<RunStatus> CheriotCLIForwarder::GetRunStatus() {
  return cheriot_cli_top_->CLIGetRunStatus();
}

// Returns the reason for the most recent halt.
absl::StatusOr<HaltReasonValueType> CheriotCLIForwarder::GetLastHaltReason() {
  return cheriot_cli_top_->CLIGetLastHaltReason();
}

// Read/write the named registers.
absl::StatusOr<uint64_t> CheriotCLIForwarder::ReadRegister(
    const std::string &name) {
  return cheriot_cli_top_->CLIReadRegister(name);
}

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

absl::StatusOr<DataBuffer *> CheriotCLIForwarder::GetRegisterDataBuffer(
    const std::string &name) {
  return cheriot_cli_top_->CLIGetRegisterDataBuffer(name);
}

// Read/write the buffers to memory.
absl::StatusOr<size_t> CheriotCLIForwarder::ReadMemory(uint64_t address,
                                                       void *buf,
                                                       size_t length) {
  return cheriot_cli_top_->CLIReadMemory(address, buf, length);
}

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

bool CheriotCLIForwarder::HasBreakpoint(uint64_t address) {
  return cheriot_cli_top_->CLIHasBreakpoint(address);
}

absl::Status CheriotCLIForwarder::SetSwBreakpoint(uint64_t address) {
  return cheriot_cli_top_->CLISetSwBreakpoint(address);
}

absl::Status CheriotCLIForwarder::ClearSwBreakpoint(uint64_t address) {
  return cheriot_cli_top_->CLIClearSwBreakpoint(address);
}

absl::Status CheriotCLIForwarder::ClearAllSwBreakpoints() {
  return cheriot_cli_top_->CLIClearAllSwBreakpoints();
}

absl::StatusOr<Instruction *> CheriotCLIForwarder::GetInstruction(
    uint64_t address) {
  return cheriot_cli_top_->CLIGetInstruction(address);
}

absl::StatusOr<std::string> CheriotCLIForwarder::GetDisassembly(
    uint64_t address) {
  return cheriot_cli_top_->CLIGetDisassembly(address);
}

}  // namespace cheriot
}  // namespace sim
}  // namespace mpact
