// 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
