// 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
//
//     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 <signal.h>

#include <cstdint>
#include <cstdlib>
#include <fstream>
#include <functional>
#include <ios>
#include <iostream>
#include <memory>
#include <optional>
#include <ostream>
#include <string>
#include <vector>

#include "absl/base/log_severity.h"
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/log/check.h"
#include "absl/log/globals.h"
#include "absl/log/log.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "mpact/sim/generic/core_debug_interface.h"
#include "mpact/sim/generic/counters.h"
#include "mpact/sim/generic/decoder_interface.h"
#include "mpact/sim/generic/instruction.h"
#include "mpact/sim/proto/component_data.pb.h"
#include "mpact/sim/util/memory/atomic_memory.h"
#include "mpact/sim/util/memory/flat_demand_memory.h"
#include "mpact/sim/util/memory/memory_interface.h"
#include "mpact/sim/util/memory/memory_watcher.h"
#include "mpact/sim/util/program_loader/elf_program_loader.h"
#include "re2/re2.h"
#include "riscv/debug_command_shell.h"
#include "riscv/riscv32_decoder.h"
#include "riscv/riscv32_htif_semihost.h"
#include "riscv/riscv32g_bitmanip_decoder.h"
#include "riscv/riscv_arm_semihost.h"
#include "riscv/riscv_csr.h"
#include "riscv/riscv_fp_state.h"
#include "riscv/riscv_register.h"
#include "riscv/riscv_register_aliases.h"
#include "riscv/riscv_state.h"
#include "riscv/riscv_top.h"
#include "src/google/protobuf/text_format.h"

using ::mpact::sim::generic::Instruction;
using ::mpact::sim::proto::ComponentData;
using ::mpact::sim::proto::ComponentValueEntry;
using ::mpact::sim::riscv::RiscV32Decoder;
using ::mpact::sim::riscv::RiscV32GBitmanipDecoder;
using ::mpact::sim::riscv::RiscV32HtifSemiHost;
using ::mpact::sim::riscv::RiscVArmSemihost;
using ::mpact::sim::riscv::RiscVFPState;
using ::mpact::sim::riscv::RiscVState;
using ::mpact::sim::riscv::RiscVXlen;
using ::mpact::sim::riscv::RV32Register;
using ::mpact::sim::riscv::RVFpRegister;

using AddressRange = mpact::sim::util::MemoryWatcher::AddressRange;

// Flags for specifying interactive mode.
ABSL_FLAG(bool, i, false, "Interactive mode");
ABSL_FLAG(bool, interactive, false, "Interactive mode");
// Flag for destination directory of proto file.
ABSL_FLAG(std::string, output_dir, "", "Output directory");
ABSL_FLAG(bool, semihost_htif, false, "HTIF semihosting");
ABSL_FLAG(bool, semihost_arm, false, "ARM semihosting");
// The RiscV gcc compiler bare metal library does not initialize the stack
// pointer before the program starts executing. It assumes that there is some
// other mechanism by which the stack pointer is initialized. For this simulator
// the stack pointer start and the stack size can be initialized in a couple of
// ways, including command line arguments, symbols defined in the executable,
// or a special program header entry in the executable.
//
// The following defines the optional flag for setting the stack size. If the
// stack size is not set using the flag, then the simulator will look in the
// executable to see if the GNU_STACK segment exists (assuming gcc RiscV
// compiler), and use that size. If not, it will use the value of the symbol
// __stack_size in the executable. If no such symbol exists, the stack size will
// be 32KB.
//
// A symbol may be defined in a C/C++ source file using asm, such as:
// asm(".global __stack_size\n"
//     ".equ __stack_size, 32 * 1024\n");
// The asm statement need not be inside a function body.
//
// The program header entry may be generated by adding the following to the
// gcc/g++ command line: -Wl,z,stack-size=N
//
ABSL_FLAG(std::optional<uint64_t>, stack_size, 32 * 1024,
          "Size of software stack");
// Optional flag for setting the location of the end of the stack (bottom). The
// beginning stack pointer is the value stack_end + stack_size. If this option
// is not set, it will use the value of the symbol __stack_end in the
// executable. If no such symbol exists, stack pointer initialization will not
// be performed by the simulator, and an appropriate crt0 library has to be
// used.
//
// A symbol may be defined in a C/C++ source file using asm, such as:
// asm(".global __stack_end\n"
//     ".equ __stack_end, 0x200000\n");
// The asm statement need not be inside a function body.
ABSL_FLAG(std::optional<uint64_t>, stack_end, 0,
          "Lowest valid address of software stack. "
          "Top of stack is stack_end + stack_size.");

// The following macro can be used in source code to define both the stack size
// and location:
//
// #define __STACK(addr, size) \
//  asm(".global __stack_size\n.equ __stack_size, " #size "\n"); \
//  asm(".global __stack_end\n.equ __stack_end, " #addr "\n");
//
// E.g.
//
// #include <stdio>
//
// __STACK(0x20000, 32 * 1024);
//
// int main(int, char **) {
//   printf("Hello World\n");
//   return 0;
// }
//

// Exit on execution of ecall instruction, default false.
ABSL_FLAG(bool, exit_on_ecall, false, "Exit on ecall - false by default");

// Enable bit manipulation instructions.
ABSL_FLAG(bool, bitmanip, false, "Enable bit manipulation instructions");

// Exit on write to 'tohost'
ABSL_FLAG(bool, exit_on_tohost, false, "Exit on write to 'tohost'");

// Quiet mode. Suppress informational and warning messages.
ABSL_FLAG(bool, quiet, false, "Suppress informational and warning messages");

// Flag to enable and configure the instruction and data caches.
ABSL_FLAG(std::string, icache, "", "Instruction cache configuration");
ABSL_FLAG(std::string, dcache, "", "Data cache configuration");

// Flag to set the default value for the misa CSR.
ABSL_FLAG(std::optional<uint64_t>, misa, std::nullopt, "misa value");

constexpr char kStackEndSymbolName[] = "__stack_end";
constexpr char kStackSizeSymbolName[] = "__stack_size";

// Static pointer to the top instance. Used by the control-C handler.
static mpact::sim::riscv::RiscVTop* top = nullptr;

// Control-c handler to interrupt any running simulation.
static void sim_sigint_handler(int arg) {
  if (top != nullptr) {
    (void)top->Halt();
    return;
  } else {
    exit(-1);
  }
}

using ::mpact::sim::riscv::RiscVTop;

// Helper function to get the magic semihosting addresses from the loader.
static bool GetMagicAddresses(mpact::sim::util::ElfProgramLoader* loader,
                              RiscV32HtifSemiHost::SemiHostAddresses* magic) {
  auto result = loader->GetSymbol("tohost_ready");
  if (!result.ok()) return false;
  magic->tohost_ready = result.value().first;

  result = loader->GetSymbol("tohost");
  if (!result.ok()) return false;
  magic->tohost = result.value().first;

  result = loader->GetSymbol("fromhost_ready");
  if (!result.ok()) return false;
  magic->fromhost_ready = result.value().first;

  result = loader->GetSymbol("fromhost");
  if (!result.ok()) return false;
  magic->fromhost = result.value().first;

  return true;
}

// This is an example custom command that is added to the interactive
// debug command shell.
static bool PrintRegisters(
    absl::string_view input,
    const mpact::sim::riscv::DebugCommandShell::CoreAccess& core_access,
    std::string& output) {
  static const LazyRE2 reg_info_re{R"(\s*xyzreg\s+info\s*)"};
  if (!RE2::FullMatch(input, *reg_info_re)) {
    return false;
  }
  std::string output_str;
  for (int i = 0; i < 32; i++) {
    std::string reg_name = absl::StrCat("x", i);
    auto result = core_access.debug_interface->ReadRegister(reg_name);
    if (!result.ok()) {
      output = absl::StrCat("Failed to read register '", reg_name, "'");
      return true;
    }
    output_str +=
        absl::StrCat("x", absl::Dec(i, absl::kZeroPad2), " = [",
                     absl::Hex(result.value(), absl::kZeroPad8), "]\n");
  }
  output = output_str;
  return true;
}

int main(int argc, char** argv) {
  int return_code = 0;
  auto arg_vec = absl::ParseCommandLine(argc, argv);

  if (absl::GetFlag(FLAGS_semihost_htif) && absl::GetFlag(FLAGS_semihost_arm)) {
    LOG(ERROR) << "Cannot specify both htif and arm semihosting";
    std::cerr << "Only one semihosting mechanism can be specified" << std::endl;
  }

  // Erase the simulator executable from arg_vec.
  arg_vec.erase(arg_vec.begin());

  bool quiet = absl::GetFlag(FLAGS_quiet);
  if (quiet) {
    absl::SetMinLogLevel(absl::LogSeverityAtLeast::kError);
  }

  std::string full_file_name = arg_vec[0];
  std::string file_name =
      full_file_name.substr(full_file_name.find_last_of('/') + 1);
  std::string file_basename = file_name.substr(0, file_name.find_first_of('.'));

  auto* memory = new mpact::sim::util::FlatDemandMemory();
  mpact::sim::util::MemoryWatcher* memory_watcher = nullptr;
  mpact::sim::util::AtomicMemory* atomic_memory = nullptr;
  if (absl::GetFlag(FLAGS_exit_on_tohost)) {
    memory_watcher = new mpact::sim::util::MemoryWatcher(memory);
    atomic_memory = new mpact::sim::util::AtomicMemory(memory_watcher);
  } else {
    atomic_memory = new mpact::sim::util::AtomicMemory(memory);
  }
  // Load the elf segments into memory.
  mpact::sim::util::ElfProgramLoader elf_loader(memory);
  auto load_result = elf_loader.LoadProgram(full_file_name);
  if (!load_result.ok()) {
    std::cerr << "Error while loading '" << full_file_name
              << "': " << load_result.status().message();
    return -1;
  }

  mpact::sim::util::MemoryInterface* memory_interface = memory;
  if (memory_watcher != nullptr) {
    memory_interface = memory_watcher;
  }
  // Set up architectural state and decoder.
  RiscVState rv_state("RiscV32", RiscVXlen::RV32, memory_interface,
                      atomic_memory);
  // For floating point support add the fp state.
  RiscVFPState rv_fp_state(rv_state.csr_set(), &rv_state);
  rv_state.set_rv_fp(&rv_fp_state);
  // Create the instruction decoder.
  mpact::sim::generic::DecoderInterface* rv_decoder = nullptr;
  if (absl::GetFlag(FLAGS_bitmanip)) {
    rv_decoder = new RiscV32GBitmanipDecoder(&rv_state, memory);
  } else {
    rv_decoder = new RiscV32Decoder(&rv_state, memory);
  }

  // Make sure the architectural and abi register aliases are added.
  std::string reg_name;
  for (int i = 0; i < 32; i++) {
    reg_name = absl::StrCat(RiscVState::kXregPrefix, i);
    (void)rv_state.AddRegister<RV32Register>(reg_name);
    (void)rv_state.AddRegisterAlias<RV32Register>(
        reg_name, ::mpact::sim::riscv::kXRegisterAliases[i]);
  }
  for (int i = 0; i < 32; i++) {
    reg_name = absl::StrCat(RiscVState::kFregPrefix, i);
    (void)rv_state.AddRegister<RVFpRegister>(reg_name);
    (void)rv_state.AddRegisterAlias<RVFpRegister>(
        reg_name, ::mpact::sim::riscv::kFRegisterAliases[i]);
  }

  if (absl::GetFlag(FLAGS_misa).has_value()) {
    auto misa_res = rv_state.csr_set()->GetCsr(
        static_cast<uint32_t>(::mpact::sim::riscv::RiscVCsrEnum::kMIsa));
    if (!misa_res.ok()) {
      LOG(FATAL) << "Failed to get misa CSR: " << misa_res.status();
    }
    auto misa_csr = misa_res.value();
    misa_csr->Set(absl::GetFlag(FLAGS_misa).value());
  }

  RiscVTop riscv_top("RiscV32Sim", &rv_state, rv_decoder);

  if (!absl::GetFlag(FLAGS_icache).empty()) {
    ComponentValueEntry icache_value;
    icache_value.set_name("icache");
    icache_value.set_string_value(absl::GetFlag(FLAGS_icache));
    auto* cfg = riscv_top.GetConfig("icache");
    auto status = cfg->Import(&icache_value);
    if (!status.ok()) return -1;
  }

  if (!absl::GetFlag(FLAGS_dcache).empty()) {
    ComponentValueEntry dcache_value;
    dcache_value.set_name("dcache");
    dcache_value.set_string_value(absl::GetFlag(FLAGS_dcache));
    auto* cfg = riscv_top.GetConfig("dcache");
    auto status = cfg->Import(&dcache_value);
    if (!status.ok()) return -1;
    // Hook the cache into the memory port.
    auto* dcache = riscv_top.dcache();
    dcache->set_memory(riscv_top.state()->memory());
    riscv_top.state()->set_memory(dcache);
  }

  if (absl::GetFlag(FLAGS_exit_on_ecall)) {
    rv_state.set_on_ecall([&riscv_top](const Instruction* inst) -> bool {
      riscv_top.RequestHalt(RiscVTop::HaltReason::kProgramDone, inst);
      return true;
    });
  }
  if (absl::GetFlag(FLAGS_exit_on_tohost)) {
    auto res = elf_loader.GetSymbol("tohost");
    if (res.ok()) {
      auto tohost_addr = res.value().first;
      auto status = memory_watcher->SetStoreWatchCallback(
          AddressRange(tohost_addr),
          [&riscv_top, tohost_addr, memory, &rv_state, &return_code, quiet](
              uint64_t, int) -> void {
            riscv_top.RequestHalt(RiscVTop::HaltReason::kProgramDone, nullptr);
            auto* db = rv_state.db_factory()->Allocate<uint32_t>(1);
            memory->Load(tohost_addr, db, nullptr, nullptr);
            auto word = db->Get<uint32_t>(0);
            db->DecRef();
            return_code = word >> 1;
            if (return_code == 0) {
              if (!quiet) std::cerr << "PASS\n";
            } else {
            }
          });
      if (!status.ok()) {
        std::cerr << "Error setting store watch callback for 'tohost': "
                  << status.message();
        return -1;
      }
    } else {
      std::cerr << "Error: no symbol 'tohost' found";
      return -1;
    }
  }

  // Initialize the PC to the entry point.
  uint32_t entry_point = load_result.value();
  auto pc_write = riscv_top.WriteRegister("pc", entry_point);
  if (!pc_write.ok()) {
    std::cerr << "Error writing to pc: " << pc_write.message();
    return -1;
  }

  // Initializing the stack pointer.

  // First see if there is a stack location defined, if not, do not initialize
  // the stack pointer.
  bool initialize_stack = false;
  uint64_t stack_end = 0;

  // Is the __stack_end symbol defined?
  auto res = elf_loader.GetSymbol(kStackEndSymbolName);
  if (res.ok()) {
    stack_end = res.value().first;
    initialize_stack = true;
  }

  // The stack_end flag overrides the __stack_end symbol.
  if (absl::GetFlag(FLAGS_stack_end).has_value()) {
    stack_end = absl::GetFlag(FLAGS_stack_end).value();
    initialize_stack = true;
  }

  // If there is a stack location, get the stack size, and write the sp.
  if (initialize_stack) {
    // Default size is 32KB.
    uint64_t stack_size = 32 * 1024;

    // Does the executable have a valid GNU_STACK segment? If so, override the
    // default
    auto loader_res = elf_loader.GetStackSize();
    if (loader_res.ok()) {
      stack_end = loader_res.value();
    }

    // If the __stack_size symbol is defined then override.
    auto res = elf_loader.GetSymbol(kStackSizeSymbolName);
    if (res.ok()) {
      stack_size = res.value().first;
    }

    // If the flag is set, then override.
    if (absl::GetFlag(FLAGS_stack_size).has_value()) {
      stack_size = absl::GetFlag(FLAGS_stack_size).value();
    }

    auto sp_write = riscv_top.WriteRegister("sp", stack_end + stack_size);
    if (!sp_write.ok()) {
      std::cerr << "Error writing to sp: " << sp_write.message();
      return -1;
    }
  }

  RiscV32HtifSemiHost* htif_semihost = nullptr;
  if (absl::GetFlag(FLAGS_semihost_htif)) {
    // Add htif semihosting.
    RiscV32HtifSemiHost::SemiHostAddresses magic_addresses;
    if (GetMagicAddresses(&elf_loader, &magic_addresses)) {
      if (memory_watcher == nullptr) {
        memory_watcher = new mpact::sim::util::MemoryWatcher(memory);
      }
      htif_semihost = new RiscV32HtifSemiHost(
          memory_watcher, memory, magic_addresses,
          [&riscv_top]() {
            riscv_top.RequestHalt(RiscVTop::HaltReason::kSemihostHaltRequest,
                                  nullptr);
          },
          [&riscv_top](std::string) {
            riscv_top.RequestHalt(RiscVTop::HaltReason::kSemihostHaltRequest,
                                  nullptr);
          });
      riscv_top.state()->set_memory(memory_watcher);
    }
  }

  RiscVArmSemihost* arm_semihost = nullptr;
  if (absl::GetFlag(FLAGS_semihost_arm)) {
    // Add ARM semihosting.
    arm_semihost = new RiscVArmSemihost(RiscVArmSemihost::BitWidth::kWord32,
                                        memory, memory);
    arm_semihost->SetCmdLine(arg_vec);
    riscv_top.state()->AddEbreakHandler(
        [arm_semihost](const Instruction* inst) -> bool {
          if (arm_semihost->IsSemihostingCall(inst)) {
            arm_semihost->OnEBreak(inst);
            return true;
          }
          return false;
        });
    arm_semihost->set_exit_callback([&riscv_top]() {
      riscv_top.RequestHalt(RiscVTop::HaltReason::kSemihostHaltRequest,
                            nullptr);
    });
  }

  mpact::sim::generic::SimpleCounter<double> counter_sec("simulation_time_sec",
                                                         0.0);

  CHECK_OK(riscv_top.AddCounter(&counter_sec));
  // Set up control-c handling.
  top = &riscv_top;
  struct sigaction sa;
  sa.sa_flags = 0;
  sigemptyset(&sa.sa_mask);
  sigaddset(&sa.sa_mask, SIGINT);
  sa.sa_handler = &sim_sigint_handler;
  sigaction(SIGINT, &sa, nullptr);

  // Determine if this is being run interactively or as a batch job.
  bool interactive = absl::GetFlag(FLAGS_i) || absl::GetFlag(FLAGS_interactive);
  if (interactive) {
    mpact::sim::riscv::DebugCommandShell cmd_shell;
    cmd_shell.AddCore({&riscv_top, [&elf_loader]() { return &elf_loader; }});
    // Add custom command to interactive debug command shell.
    cmd_shell.AddCommand(
        "    reg info                       - print all scalar regs",
        PrintRegisters);
    cmd_shell.Run(std::cin, std::cout);
  } else {
    if (!quiet) std::cerr << "Starting simulation\n";

    auto t0 = absl::Now();

    auto run_status = riscv_top.Run();
    if (!run_status.ok()) {
      std::cerr << run_status.message() << std::endl;
    }

    auto wait_status = riscv_top.Wait();
    if (!wait_status.ok()) {
      std::cerr << wait_status.message() << std::endl;
    }

    auto t1 = absl::Now();
    absl::Duration duration = t1 - t0;
    double sec = static_cast<double>(duration / absl::Milliseconds(100)) / 10;
    counter_sec.SetValue(sec);

    if (!quiet)
      std::cerr << absl::StrFormat("Simulation done: %0.1f sec\n", sec)
                << std::endl;
  }

  // Export counters.
  auto component_proto = std::make_unique<ComponentData>();
  CHECK_OK(riscv_top.Export(component_proto.get())) << "Failed to export proto";
  std::string proto_file_name;
  if (FLAGS_output_dir.CurrentValue().empty()) {
    proto_file_name = "./" + file_basename + ".proto";
  } else {
    proto_file_name =
        FLAGS_output_dir.CurrentValue() + "/" + file_basename + ".proto";
  }
  std::fstream proto_file(proto_file_name.c_str(), std::ios_base::out);
  std::string serialized;
  if (!proto_file.good() || !google::protobuf::TextFormat::PrintToString(
                                *component_proto, &serialized)) {
    LOG(ERROR) << "Failed to write proto to file";
  } else {
    proto_file << serialized;
    proto_file.close();
  }

  // Cleanup.
  auto status = riscv_top.ClearAllSwBreakpoints();
  if (!status.ok()) {
    LOG(ERROR) << "Error in ClearAllSwBreakpoints: " << status.message();
  }
  delete atomic_memory;
  delete memory;
  delete htif_semihost;
  delete memory_watcher;
  delete arm_semihost;
  delete rv_decoder;
  return return_code;
}
