// 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
//
//     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/util/renode/renode_mpact.h"

#include <cstddef>
#include <cstdint>
#include <cstring>
#include <fstream>
#include <ios>
#include <limits>
#include <string>

#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "mpact/sim/generic/core_debug_interface.h"
#include "mpact/sim/generic/type_helpers.h"
#include "mpact/sim/util/memory/memory_interface.h"
#include "mpact/sim/util/renode/renode_debug_interface.h"
#include "mpact/sim/util/renode/renode_memory_access.h"

using ::mpact::sim::generic::operator*;  // NOLINT: used below (clang error).
using ::mpact::sim::util::MemoryInterface;

// This function must be defined in the library.
extern ::mpact::sim::util::renode::RenodeDebugInterface *CreateMpactSim(
    std::string name, std::string cpu_type, MemoryInterface *);

using ::mpact::sim::util::renode::RenodeAgent;
using ::mpact::sim::util::renode::RenodeCpuRegister;

// Implementation of the C interface functions. They each forward the call to
// the corresponding method in RenodeAgent.
int32_t construct(char *cpu_type, int32_t max_name_length) {
  return RenodeAgent::Instance()->Construct(cpu_type, max_name_length, nullptr,
                                            nullptr);
}

int32_t construct_with_sysbus(char *cpu_type, int32_t max_name_length,
                              int32_t (*read_callback)(uint64_t, char *,
                                                       int32_t),
                              int32_t (*write_callback)(uint64_t, char *,
                                                        int32_t)) {
  return RenodeAgent::Instance()->Construct(cpu_type, max_name_length,
                                            read_callback, write_callback);
}

int32_t connect(char *cpu_type, int32_t id, int32_t max_name_length) {
  return RenodeAgent::Instance()->Connect(cpu_type, id, max_name_length,
                                          nullptr, nullptr);
}

int32_t connect_with_sysbus(char *cpu_type, int32_t id, int32_t max_name_length,
                            int32_t (*read_callback)(uint64_t, char *, int32_t),
                            int32_t (*write_callback)(uint64_t, char *,
                                                      int32_t)) {
  return RenodeAgent::Instance()->Connect(cpu_type, id, max_name_length,
                                          read_callback, write_callback);
}

void destruct(int32_t id) { RenodeAgent::Instance()->Destroy(id); }

int32_t reset(int32_t id) { return RenodeAgent::Instance()->Reset(id); }

int32_t get_reg_info_size(int32_t id) {
  return RenodeAgent::Instance()->GetRegisterInfoSize(id);
}

int32_t get_reg_info(int32_t id, int32_t index, char *name, void *info) {
  if (info == nullptr) return -1;
  return RenodeAgent::Instance()->GetRegisterInfo(
      id, index, name, static_cast<RenodeCpuRegister *>(info));
}

uint64_t load_elf(int32_t id, const char *elf_file_name, bool for_symbols_only,
                  int32_t *status) {
  return RenodeAgent::Instance()->LoadExecutable(id, elf_file_name,
                                                 for_symbols_only, status);
}

int32_t load_image(int32_t id, const char *file_name, uint64_t address) {
  return RenodeAgent::Instance()->LoadImage(id, file_name, address);
}

int32_t read_register(int32_t id, uint32_t reg_id, uint64_t *value) {
  return RenodeAgent::Instance()->ReadRegister(id, reg_id, value);
}

int32_t write_register(int32_t id, uint32_t reg_id, uint64_t value) {
  return RenodeAgent::Instance()->WriteRegister(id, reg_id, value);
}

uint64_t read_memory(int32_t id, uint64_t address, char *buffer,
                     uint64_t length) {
  return RenodeAgent::Instance()->ReadMemory(id, address, buffer, length);
}

uint64_t write_memory(int32_t id, uint64_t address, const char *buffer,
                      uint64_t length) {
  return RenodeAgent::Instance()->WriteMemory(id, address, buffer, length);
}

uint64_t step(int32_t id, uint64_t num_to_step, int32_t *status) {
  return RenodeAgent::Instance()->Step(id, num_to_step, status);
}

int32_t set_config(int32_t id, const char *config_names[],
                   const char *config_values[], int32_t size) {
  return RenodeAgent::Instance()->SetConfig(id, config_names, config_values,
                                            size);
}

int32_t set_irq_value(int32_t id, int32_t irq_num, bool irq_value) {
  return RenodeAgent::Instance()->SetIrqValue(id, irq_num, irq_value);
}

namespace mpact {
namespace sim {
namespace util {
namespace renode {

using HaltReason = ::mpact::sim::generic::CoreDebugInterface::HaltReason;

RenodeAgent *RenodeAgent::instance_ = nullptr;
int32_t RenodeAgent::count_ = 0;

// Create the debug instance by calling the factory function.
int32_t RenodeAgent::Construct(char *cpu_type, int32_t max_name_length,
                               int32_t (*read_callback)(uint64_t, char *,
                                                        int32_t),
                               int32_t (*write_callback)(uint64_t, char *,
                                                         int32_t)) {
  std::string name = absl::StrCat("renode", count_);
  auto *memory_access = new RenodeMemoryAccess(read_callback, write_callback);
  auto *dbg = CreateMpactSim(name, cpu_type, memory_access);
  if (dbg == nullptr) {
    delete memory_access;
    return -1;
  }
  // Make sure that we don't reuse an instance number that may have been created
  // through Connect.
  while (core_dbg_instances_.contains(RenodeAgent::count_)) {
    RenodeAgent::count_++;
  }
  core_dbg_instances_.emplace(RenodeAgent::count_, dbg);
  name_length_map_.emplace(RenodeAgent::count_, max_name_length);
  renode_memory_access_.emplace(RenodeAgent::count_, memory_access);
  return RenodeAgent::count_++;
}

int32_t RenodeAgent::Connect(
    char *cpu_type, int32_t id, int32_t max_name_length,
    int32_t (*read_callback)(uint64_t, char *, int32_t),
    int32_t (*write_callback)(uint64_t, char *, int32_t)) {
  // First check if the instance already exists.
  auto iter = core_dbg_instances_.find(id);
  if (iter != core_dbg_instances_.end()) {
    // If memory callbacks are provided, don't overwrite any previous non-null
    // callbacks.
    auto *mem_access = renode_memory_access_.at(id);
    // Replace any null callbacks.
    if (!mem_access->has_read_fcn()) {
      mem_access->set_read_fcn(read_callback);
    }
    if (!mem_access->has_write_fcn()) {
      mem_access->set_write_fcn(write_callback);
    }
    return id;
  }

  // The instance does not exist, so create a new debug instance.
  std::string name = absl::StrCat("renode", id);
  auto *memory_access = new RenodeMemoryAccess(read_callback, write_callback);
  auto *dbg = CreateMpactSim(name, cpu_type, memory_access);
  if (dbg == nullptr) {
    delete memory_access;
    return -1;
  }
  core_dbg_instances_.emplace(id, dbg);
  name_length_map_.emplace(id, max_name_length);
  renode_memory_access_.emplace(id, memory_access);
  return id;
}

// Destroy the debug instance.
void RenodeAgent::Destroy(int32_t id) {
  // Check for valid instance.
  auto dbg_iter = core_dbg_instances_.find(id);
  // If it doesn't exist, it may already have been deleted, so just return.
  if (dbg_iter == core_dbg_instances_.end()) return;

  delete dbg_iter->second;
  core_dbg_instances_.erase(dbg_iter);

  // Delete the memory access shim.
  auto mem_iter = renode_memory_access_.find(id);
  if (mem_iter == renode_memory_access_.end()) return;
  delete mem_iter->second;
  renode_memory_access_.erase(mem_iter);
}

int32_t RenodeAgent::Reset(int32_t id) {
  // Check for valid instance.
  auto dbg_iter = core_dbg_instances_.find(id);
  if (dbg_iter == core_dbg_instances_.end()) return -1;

  // For now, do nothing.
  return 0;
}

int32_t RenodeAgent::GetRegisterInfoSize(int32_t id) const {
  // Check for valid instance.
  auto dbg_iter = core_dbg_instances_.find(id);
  if (dbg_iter == core_dbg_instances_.end()) return -1;
  auto *dbg = dbg_iter->second;
  return dbg->GetRenodeRegisterInfoSize();
}

int32_t RenodeAgent::GetRegisterInfo(int32_t id, int32_t index, char *name,
                                     RenodeCpuRegister *info) {
  // Check for valid instance.
  if (info == nullptr) return -1;
  auto dbg_iter = core_dbg_instances_.find(id);
  if (dbg_iter == core_dbg_instances_.end()) return -1;
  auto *dbg = dbg_iter->second;
  int32_t max_len = name_length_map_.at(id);
  auto result = dbg->GetRenodeRegisterInfo(index, max_len, name, *info);
  if (!result.ok()) return -1;
  return 0;
}

// Read the register given by the id.
int32_t RenodeAgent::ReadRegister(int32_t id, uint32_t reg_id,
                                  uint64_t *value) {
  // Check for valid instance.
  if (value == nullptr) return -1;
  auto dbg_iter = core_dbg_instances_.find(id);
  if (dbg_iter == core_dbg_instances_.end()) return -1;
  // Read register.
  auto *dbg = dbg_iter->second;
  auto result = dbg->ReadRegister(reg_id);
  if (!result.ok()) return -1;
  *value = result.value();
  return 0;
}

int32_t RenodeAgent::WriteRegister(int32_t id, uint32_t reg_id,
                                   uint64_t value) {
  // Check for valid instance.
  auto dbg_iter = core_dbg_instances_.find(id);
  if (dbg_iter == core_dbg_instances_.end()) return -1;
  // Write register.
  auto *dbg = dbg_iter->second;
  auto result = dbg->WriteRegister(reg_id, value);
  if (!result.ok()) return -1;
  return 0;
}

uint64_t RenodeAgent::ReadMemory(int32_t id, uint64_t address, char *buffer,
                                 uint64_t length) {
  // Get the debug interface.
  auto dbg_iter = core_dbg_instances_.find(id);
  if (dbg_iter == core_dbg_instances_.end()) {
    LOG(ERROR) << "No such core dbg instance: " << id;
    return 0;
  }
  auto *dbg = dbg_iter->second;
  auto res = dbg->ReadMemory(address, buffer, length);
  if (!res.ok()) return 0;
  return res.value();
}

uint64_t RenodeAgent::WriteMemory(int32_t id, uint64_t address,
                                  const char *buffer, uint64_t length) {
  // Get the debug interface.
  auto dbg_iter = core_dbg_instances_.find(id);
  if (dbg_iter == core_dbg_instances_.end()) {
    LOG(ERROR) << "No such core dbg instance: " << id;
    return 0;
  }
  auto *dbg = dbg_iter->second;
  auto res = dbg->WriteMemory(address, buffer, length);
  if (!res.ok()) return 0;
  return res.value();
}

uint64_t RenodeAgent::LoadExecutable(int32_t id, const char *file_name,
                                     bool for_symbols_only, int32_t *status) {
  // Get the debug interface.
  auto dbg_iter = core_dbg_instances_.find(id);
  if (dbg_iter == core_dbg_instances_.end()) {
    LOG(ERROR) << "No such core dbg instance: " << id;
    *status = -1;
    return 0;
  }
  // Instantiate loader.
  auto *dbg = dbg_iter->second;
  auto res = dbg->LoadExecutable(file_name, for_symbols_only);
  if (!res.ok()) {
    LOG(ERROR) << "Failed to load executable: " << res.status().message();
    *status = -1;
    return 0;
  }
  *status = 0;
  uint64_t entry = res.value();
  return entry;
}

int32_t RenodeAgent::LoadImage(int32_t id, const char *file_name,
                               uint64_t address) {
  // Get the debug interface.
  auto dbg_iter = core_dbg_instances_.find(id);
  if (dbg_iter == core_dbg_instances_.end()) {
    LOG(ERROR) << "No such core dbg instance: " << id;
    return -1;
  }
  auto *dbg = dbg_iter->second;
  // Open up the image file.
  std::ifstream image_file;
  image_file.open(file_name, std::ios::in | std::ios::binary);
  if (!image_file.good()) {
    LOG(ERROR) << "LoadImage: Input file not in good state";
    return -1;
  }
  char buffer[kBufferSize];
  size_t gcount = 0;
  uint64_t load_address = address;
  do {
    // Fill buffer.
    image_file.read(buffer, kBufferSize);
    // Get the number of bytes that was read.
    gcount = image_file.gcount();
    // Write to the simulator memory.
    auto res = dbg->WriteMemory(load_address, buffer, gcount);
    // Check that the write succeeded, increment address if it did.
    if (!res.ok()) {
      LOG(ERROR) << "LoadImage: Memory write failed";
      return -1;
    }
    if (res.value() != gcount) {
      LOG(ERROR) << "LoadImage: Memory write failed to write all the bytes";
      return -1;
    }
    load_address += gcount;
  } while (image_file.good() && (gcount > 0));
  return 0;
}

uint64_t RenodeAgent::Step(int32_t id, uint64_t num_to_step, int32_t *status) {
  // Get the core debug if object.
  auto *dbg = RenodeAgent::Instance()->core_dbg(id);
  // Is the debug interface valid?
  if (dbg == nullptr) {
    if (status != nullptr) {
      *status = static_cast<int32_t>(ExecutionResult::kAborted);
    }
    return 0;
  }

  if (num_to_step == 0) {
    *status = static_cast<int32_t>(ExecutionResult::kOk);
    return 0;
  }

  // Check the previous halt reason.
  auto halt_res = dbg->GetLastHaltReason();
  if (!halt_res.ok()) {
    if (status != nullptr) {
      *status = static_cast<int32_t>(ExecutionResult::kAborted);
    }
    return 0;
  }

  // If the previous halt reason was a semihost halt request, then we
  // shouldn't step any further. Just return with "waiting for interrupt"
  // code.
  if (halt_res.value() ==
      *RenodeDebugInterface::HaltReason::kSemihostHaltRequest) {
    *status = static_cast<int32_t>(ExecutionResult::kAborted);
    return 0;
  }
  // Perform the stepping.
  uint32_t total_executed = 0;
  while (num_to_step > 0) {
    // Check how far to step, and make multiple calls if the number
    // is greater than <int>::max();
    int step_count = (num_to_step > std::numeric_limits<int>::max())
                         ? std::numeric_limits<int>::max()
                         : static_cast<int>(num_to_step);
    auto res = dbg->Step(step_count);
    // An error occurred.
    if (!res.ok()) {
      if (status != nullptr) {
        *status = static_cast<int32_t>(ExecutionResult::kAborted);
      }
      return total_executed;
    }
    int num_executed = res.value();
    total_executed += num_executed;

    // Check if the execution was halted due to a semihosting halt request,
    // i.e., program exit.
    halt_res = dbg->GetLastHaltReason();
    if (!halt_res.ok()) {
      if (status != nullptr) {
        *status = static_cast<int32_t>(ExecutionResult::kAborted);
      }
      return total_executed;
    }
    if (halt_res.value() == *HaltReason::kProgramDone) {
      if (status != nullptr) {
        *status = static_cast<int32_t>(ExecutionResult::kAborted);
      }
      return total_executed;
    }
    if (halt_res.value() ==
        *RenodeDebugInterface::HaltReason::kSemihostHaltRequest) {
      if (status != nullptr) {
        *status = static_cast<uint32_t>(ExecutionResult::kAborted);
      }
      return total_executed;
    }
    // Check if the execution ended at a software breakpoint.
    if (halt_res.value() ==
        *RenodeDebugInterface::HaltReason::kSoftwareBreakpoint) {
      if (status != nullptr) {
        *status = static_cast<int32_t>(ExecutionResult::kStoppedAtBreakpoint);
      }
      return total_executed;
    }
    // If we stepped fewer instructions than anticipated, stop stepping and
    // return with no error.
    if (num_executed < step_count) {
      if (status != nullptr) {
        *status = static_cast<int32_t>(ExecutionResult::kOk);
      }
      return total_executed;
    }
    num_to_step -= num_executed;
  }
  if (status != nullptr) {
    *status = static_cast<int32_t>(ExecutionResult::kOk);
  }
  return total_executed;
}

// Set configuration item.
int32_t RenodeAgent::SetConfig(int32_t id, const char *config_names[],
                               const char *config_values[], int size) {
  // Get the core debug interface object.
  auto *dbg = RenodeAgent::Instance()->core_dbg(id);
  // Is the debug interface valid?
  if (dbg == nullptr) {
    return -1;
  }
  auto status = dbg->SetConfig(config_names, config_values, size);
  if (!status.ok()) {
    LOG(ERROR) << "SetConfig: " << status.message();
    return -1;
  }
  return 0;
}

// Set irq value.
int32_t RenodeAgent::SetIrqValue(int32_t id, int32_t irq_num, bool irq_value) {
  // Get the core debug interface object.
  auto *dbg = RenodeAgent::Instance()->core_dbg(id);
  // Is the debug interface valid?
  if (dbg == nullptr) {
    return -1;
  }
  auto status = dbg->SetIrqValue(irq_num, irq_value);
  if (!status.ok()) {
    LOG(ERROR) << "SetIrqValue: " << status.message();
    return -1;
  }
  return 0;
}

}  // namespace renode
}  // namespace util
}  // namespace sim
}  // namespace mpact
