// 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 <fstream>
#include <iomanip>
#include <ios>
#include <iostream>
#include <optional>
#include <ostream>
#include <string>
#include <vector>

#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/log/log.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "mpact/sim/generic/core_debug_interface.h"
#include "mpact/sim/generic/type_helpers.h"
#include "mpact/sim/util/memory/atomic_memory.h"
#include "mpact/sim/util/memory/flat_demand_memory.h"
#include "mpact/sim/util/memory/memory_watcher.h"
#include "mpact/sim/util/program_loader/elf_program_loader.h"
#include "riscv/riscv64_decoder.h"
#include "riscv/riscv_register.h"
#include "riscv/riscv_state.h"
#include "riscv/riscv_test_mem_watcher.h"
#include "riscv/riscv_top.h"

// This top level is customized to execute tests generated by
// https://github.com/riscv-software-src/riscv-tests and report the results.

using HaltReason = ::mpact::sim::generic::CoreDebugInterface::HaltReason;
using HaltReasonValueType =
    ::mpact::sim::generic::CoreDebugInterface::HaltReasonValueType;
using AddressRange = ::mpact::sim::util::MemoryWatcher::AddressRange;
using ::mpact::sim::generic::operator*;  // NOLINT: clang-tidy false positive.
using ::mpact::sim::riscv::RiscV64Decoder;
using ::mpact::sim::riscv::RiscVFPState;
using ::mpact::sim::riscv::RiscVState;
using ::mpact::sim::riscv::RiscVTop;
using ::mpact::sim::riscv::RiscVXlen;
using ::mpact::sim::riscv::RV64Register;
using ::mpact::sim::riscv::RVFpRegister;

constexpr char kBeginSignature[] = "begin_signature";
constexpr char kEndSignature[] = "end_signature";

ABSL_FLAG(std::optional<std::string>, dump_signature, std::nullopt,
          "Dump signature file name (riscv torture test)");
ABSL_FLAG(bool, log_commits, false, "Log commits similar to spike");
ABSL_FLAG(int64_t, max_cycles, -1, "Max cycles to simulate");

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

  if (arg_vec.size() > 2) {
    std::cerr << "Only a single input file allowed" << std::endl;
    return -1;
  }
  std::string full_file_name = arg_vec[1];
  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('.'));

  mpact::sim::util::FlatDemandMemory memory;
  auto *watcher = new mpact::sim::util::MemoryWatcher(&memory);
  auto *test_watcher = new mpact::sim::riscv::RiscVTestMemWatcher(watcher);
  auto *atomic_memory = new mpact::sim::util::AtomicMemory(test_watcher);
  // 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;
  }
  // Set up architectural state and decoder.
  RiscVState rv_state("RiscV64", RiscVXlen::RV64, test_watcher, 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.
  RiscV64Decoder rv_decoder(&rv_state, watcher);

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

  // Initialize the PC to the entry point.
  uint64_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;
  }

  // The test result gets stored to label <tohost>, so set a watchpoint there.
  auto result = elf_loader.GetSymbol("tohost");
  if (!result.ok()) {
    std::cerr << "Cannot find symbol 'tohost'";
    return -1;
  }
  auto tohost = result.value().first;
  auto status = watcher->SetStoreWatchCallback(
      AddressRange(tohost), [&riscv_top](uint64_t, int) -> void {
        riscv_top.RequestHalt(RiscVTop::HaltReason::kUserRequest, nullptr);
      });

  if (!status.ok()) {
    std::cerr << "Cannot set watcher callback";
    return -1;
  }

  // Run the executable.
  HaltReasonValueType halt_reason;
  bool ok = true;
  uint64_t pc = entry_point;
  bool commit_trace = absl::GetFlag(FLAGS_log_commits);
  auto *register_map = riscv_top.state()->registers();
  mpact::sim::generic::DataBuffer *inst_db =
      riscv_top.state()->db_factory()->Allocate<uint32_t>(1);
  int64_t count = 0;
  int64_t max_count = absl::GetFlag(FLAGS_max_cycles);
  do {
    ok = false;
    auto status = riscv_top.Step(1);
    if (!status.ok()) break;
    count++;
    if (max_count > 0 && count > max_count) {
      riscv_top.RequestHalt(RiscVTop::HaltReason::kUserRequest, nullptr);
    }
    auto halt_status = riscv_top.GetLastHaltReason();
    if (!halt_status.ok()) break;
    halt_reason = halt_status.value();
    ok = true;
    if (commit_trace) {
      // This IncRef's the inst instance. Need to DecRef it when we are done.
      auto *inst = riscv_top.GetInstruction(pc).value();
      std::string trace_str;
      absl::StrAppend(
          &trace_str, "core   0: ", *(riscv_top.state()->privilege_mode()),
          " 0x", absl::Hex(inst->address(), absl::PadSpec::kZeroPad16));
      memory.Load(inst->address(), inst_db, nullptr, nullptr);
      absl::StrAppend(
          &trace_str, " (0x",
          absl::Hex(inst_db->Get<uint32_t>(0), absl::PadSpec::kZeroPad8), ")");
      for (int i = 0; i < inst->DestinationsSize(); ++i) {
        auto *dest = inst->Destination(i);
        if (dest == nullptr) continue;
        auto name = dest->AsString();
        if (name == "pc") continue;
        if (name == "x0") continue;
        auto iter = register_map->find(name);
        if (iter == register_map->end()) {
          continue;
        } else {
          auto *db = iter->second->data_buffer();
          auto size = db->size<uint8_t>();
          if (size != sizeof(uint64_t)) {
            continue;
          }
          absl::StrAppend(
              &trace_str, " ", absl::StrFormat("%-3s", name), " 0x",
              absl::Hex(db->Get<uint64_t>(0), absl::PadSpec::kZeroPad16));
        }
      }
      auto *child = inst->child();
      while (child != nullptr) {
        for (int i = 0; i < child->DestinationsSize(); ++i) {
          auto *dest = child->Destination(i);
          if (dest == nullptr) continue;
          auto name = dest->AsString();
          if (name == "pc") continue;
          if (name == "x0") continue;
          auto iter = register_map->find(name);
          if (iter == register_map->end()) {
            continue;
          } else {
            auto *db = iter->second->data_buffer();
            auto size = db->size<uint8_t>();
            if (size != sizeof(uint64_t)) {
              absl::StrAppend(&trace_str, " size issue:  ", name);
              continue;
            }
            absl::StrAppend(
                &trace_str, " ", absl::StrFormat("%-3s", name), " 0x",
                absl::Hex(db->Get<uint64_t>(0), absl::PadSpec::kZeroPad16));
          }
        }
        child = child->next();
      }
      trace_str.append(test_watcher->trace_str());
      test_watcher->clear_trace_str();
      std::cerr << trace_str << std::endl;
      inst->DecRef();
    }
    pc = riscv_top.ReadRegister("pc").value();
  } while (halt_reason == *HaltReason::kNone);

  if (!ok) {
    std::cerr << "Failure in stepping or obtaining halt reason";
    return -1;
  }

  // Read PC, see where we halted.
  auto pc_read = riscv_top.ReadRegister("pc");
  if (!pc_read.ok()) {
    std::cerr << "Failed to read pc: " << pc_read.status().message();
    return -1;
  }

  int ret = -1;
  if (halt_reason == *HaltReason::kUserRequest) {
    auto db = riscv_top.state()->db_factory()->Allocate<uint32_t>(1);
    memory.Load(tohost, db, nullptr, nullptr);
    auto value = db->Get<uint32_t>(0);
    db->DecRef();
    if (value == 1) {
      std::cerr << "PASS (" << value << ")\n";
      ret = 0;
    } else {
      std::cerr << "FAIL (" << value << ")\n";
      ret = -1;
    }
  }

  // Check to see if we need to dump the riscv torture signature section.
  if (absl::GetFlag(FLAGS_dump_signature).has_value()) {
    std::string file_name = absl::GetFlag(FLAGS_dump_signature).value();
    std::fstream sig_file(file_name.c_str(), std::ios_base::out);
    auto begin_res = elf_loader.GetSymbol(kBeginSignature);
    auto end_res = elf_loader.GetSymbol(kEndSignature);
    if (!begin_res.ok() || !end_res.ok()) {
      std::cerr << "Unable to find signature symbols";
    } else {
      uint64_t begin_sig = begin_res.value().first;
      uint64_t end_sig = end_res.value().first;
      uint64_t length = end_sig - begin_sig;
      uint8_t *buffer = new uint8_t[length];
      auto status = riscv_top.ReadMemory(begin_sig, buffer, length);
      sig_file << std::setfill('0') << std::hex;
      for (int i = 0; i < length; i += 16) {
        for (int j = 16; j > 0; j--) {
          if (i + j <= length) {
            sig_file << std::setw(2)
                     << static_cast<uint16_t>(buffer[i + j - 1]);
          } else {
            sig_file << std::setw(2) << 0;
          }
        }
        sig_file << std::endl;
      }
      delete[] buffer;
      sig_file.close();
    }
  }

  delete atomic_memory;
  delete watcher;
  return ret;
}
