// Copyright 2025 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 <cstdint>
#include <sstream>
#include <string>
#include <vector>

#include "absl/base/no_destructor.h"
#include "absl/container/flat_hash_map.h"
#include "absl/log/check.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "elfio/elf_types.hpp"
#include "elfio/elfio.hpp"
#include "elfio/elfio_strings.hpp"
#include "elfio/elfio_symbols.hpp"
#include "googlemock/include/gmock/gmock.h"  // IWYU pragma: keep
#include "googletest/include/gtest/gtest.h"
#include "mpact/sim/util/asm/opcode_assembler_interface.h"
#include "mpact/sim/util/asm/resolver_interface.h"
#include "mpact/sim/util/asm/simple_assembler.h"
#include "mpact/sim/util/asm/test/riscv64x_bin_encoder_interface.h"
#include "mpact/sim/util/asm/test/riscv64x_encoder.h"
#include "re2/re2.h"

// This file contains tests for the simple assembler using a very reduced
// subset of the RISC-V ISA.

namespace {

using ::mpact::sim::riscv::isa64::RiscV64XBinEncoderInterface;
using ::mpact::sim::riscv::isa64::Riscv64xSlotMatcher;
using ::mpact::sim::util::assembler::OpcodeAssemblerInterface;
using ::mpact::sim::util::assembler::RelocationInfo;
using ::mpact::sim::util::assembler::ResolverInterface;
using ::mpact::sim::util::assembler::SimpleAssembler;

// This class implements the OpcodeAssemblerInterface using the slot matcher.
class RiscV64XAssembler : public OpcodeAssemblerInterface {
 public:
  RiscV64XAssembler(Riscv64xSlotMatcher* matcher)
      : label_re_("^(\\S+)\\s*:"), matcher_(matcher) {};
  ~RiscV64XAssembler() override = default;
  absl::Status Encode(uint64_t address, absl::string_view text,
                      AddSymbolCallback add_symbol_callback,
                      ResolverInterface* resolver, std::vector<uint8_t>& bytes,
                      std::vector<RelocationInfo>& relocations) override {
    // First check to see if there is a label, if so, add it to the symbol table
    // with the current address.
    std::string label;
    if (RE2::Consume(&text, label_re_, &label)) {
      auto status = add_symbol_callback(label, address, 0, STT_NOTYPE, 0, 0);
      if (!status.ok()) return status;
    }
    // Call the slot matcher to get the encoded value.
    auto res = matcher_->Encode(address, text, 0, resolver, relocations);
    if (!res.status().ok()) return res.status();
    // Convert the value to a byte array.
    auto [value, size] = res.value();
    union {
      uint64_t i;
      uint8_t b[sizeof(uint64_t)];
    } u;
    u.i = value;
    for (int i = 0; i < size / 8; ++i) {
      bytes.push_back(u.b[i]);
    }
    return absl::OkStatus();
  }

 private:
  RE2 label_re_;
  Riscv64xSlotMatcher* matcher_;
};

// Sample assembly code.
absl::NoDestructor<std::string> kTestAssembly(R"(
; text section
    .text
    .global main
main:
    addi a0, zero, 5
    lui a1, %hi(semihost_param)
    addi a1, a1, %lo(semihost_param)
    addi t0, zero, 2
    sd t0, 0(a1)
    lui t2, %hi(hello)
    addi t2, t2, %lo(hello)
    sd t2, 8(a1)
    addi t0, zero, 12
    sd t0, 0x10(a1)
    jal ra, semihost
    ; now exit
    addi a0, zero, 24
    lui t0, 0x20026
    addi t0, t0, 0x20026
    sd t0, 0(a1)
    jal ra, semihost
exit:
    j exit

semihost:
    slli zero, zero, 0x1f
    ebreak
    srai zero, zero, 7
    jr ra, 0

; data section

    .data
    .global hello
hello:
    .cstring "Hello World\n"
    .char '\n'

; bss

    .bss
    .global tohost
tohost:
    .space 16
semihost_param:
    .space 16
)");

// Test fixture. It creates the assembler and parses the assembly code.
class RiscV64XAssemblerTest : public ::testing::Test {
 protected:
  RiscV64XAssemblerTest()
      : matcher_(&bin_encoder_interface_), riscv_64x_assembler_(&matcher_) {
    CHECK_OK(matcher_.Initialize());
    // Create the assembler.
    assembler_ = new SimpleAssembler(";", ELFCLASS64, &riscv_64x_assembler_);
    assembler_->writer().set_os_abi(ELFOSABI_LINUX);
    assembler_->writer().set_machine(EM_RISCV);
    std::istringstream source(*kTestAssembly);
    // Parse the assembly code.
    auto status = assembler_->Parse(source);
    CHECK_OK(status) << status.message();
  }

  ~RiscV64XAssemblerTest() override { delete assembler_; }

  // Access the ELF writer.
  ELFIO::elfio& elf() { return assembler_->writer(); }
  SimpleAssembler* assembler() const { return assembler_; }

 private:
  RiscV64XBinEncoderInterface bin_encoder_interface_;
  Riscv64xSlotMatcher matcher_;
  RiscV64XAssembler riscv_64x_assembler_;
  SimpleAssembler* assembler_;
};

// Test that the expected sections are present.
TEST_F(RiscV64XAssemblerTest, Sections) {
  auto sections = elf().sections;
  // Null section and the 6 sections listed below.
  EXPECT_EQ(sections.size(), 7);
  EXPECT_NE(sections[".text"], nullptr);
  EXPECT_NE(sections[".data"], nullptr);
  EXPECT_NE(sections[".bss"], nullptr);
  EXPECT_NE(sections[".shstrtab"], nullptr);
  EXPECT_NE(sections[".strtab"], nullptr);
  EXPECT_NE(sections[".symtab"], nullptr);
}

// Verify that the information about the text section is as expected.
TEST_F(RiscV64XAssemblerTest, Text) {
  auto status = assembler()->CreateExecutable(0x1000, "main");
  CHECK_OK(status) << status.message();
  auto* text = elf().sections[".text"];
  EXPECT_EQ(text->get_type(), SHT_PROGBITS);
  EXPECT_EQ(text->get_flags(), SHF_ALLOC | SHF_EXECINSTR);
  EXPECT_EQ(text->get_link(), SHN_UNDEF);
  EXPECT_EQ(text->get_size(), /*num inst*/ 21 * /*bytes per inst*/ 4);
}

TEST_F(RiscV64XAssemblerTest, Data) {
  auto status = assembler()->CreateExecutable(0x1000, "main");
  CHECK_OK(status) << status.message();
  auto* data = elf().sections[".data"];
  EXPECT_EQ(data->get_type(), SHT_PROGBITS);
  EXPECT_EQ(data->get_flags(), SHF_ALLOC | SHF_WRITE);
  EXPECT_EQ(data->get_link(), SHN_UNDEF);
  // Hello world is 12 bytes, plus the null terminator.
  // Add one .char declaration.
  EXPECT_EQ(data->get_size(), 14);
}

TEST_F(RiscV64XAssemblerTest, Bss) {
  auto status = assembler()->CreateExecutable(0x1000, "main");
  CHECK_OK(status) << status.message();
  auto* bss = elf().sections[".bss"];
  EXPECT_EQ(bss->get_type(), SHT_NOBITS);
  EXPECT_EQ(bss->get_flags(), SHF_ALLOC | SHF_WRITE);
  EXPECT_EQ(bss->get_link(), SHN_UNDEF);
  // Two .space declarations, each 16 bytes.
  EXPECT_EQ(bss->get_size(), 32);
}

TEST_F(RiscV64XAssemblerTest, RelocatableSymbols) {
  auto status = assembler()->CreateRelocatable();
  CHECK_OK(status) << status.message();
  auto* symtab = elf().sections[".symtab"];
  ELFIO::symbol_section_accessor symbols(elf(), symtab);
  ELFIO::Elf64_Addr value;
  ELFIO::Elf_Xword size;
  unsigned char bind;
  unsigned char type;
  ELFIO::Elf_Half section_index;
  unsigned char other;
  int num_symbols = symtab->get_size() / sizeof(ELFIO::Elf64_Sym);
  auto symspan = absl::MakeSpan(
      reinterpret_cast<const ELFIO::Elf64_Sym*>(symtab->get_data()),
      num_symbols);
  absl::flat_hash_map<std::string, int> symbol_map;
  auto* string_accessor =
      new ELFIO::string_section_accessor(elf().sections[".strtab"]);
  for (int i = 0; i < num_symbols; ++i) {
    auto name = string_accessor->get_string(symspan[i].st_name);
    symbol_map.insert({name, i});
  }
  // Verify that main is valued 0x0, global and located in the text section.
  symbols.get_symbol("main", value, size, bind, type, section_index, other);
  auto* sym = &symspan[symbol_map["main"]];
  EXPECT_EQ(sym->st_value, 0x0);
  EXPECT_EQ(ELF_ST_BIND(sym->st_info), STB_GLOBAL);
  EXPECT_EQ(sym->st_shndx, elf().sections[".text"]->get_index());
  EXPECT_EQ(ELF_ST_TYPE(sym->st_info), STT_NOTYPE);
  // Verify that exit is valued 16 * 4, local and located in the text
  // section.
  sym = &symspan[symbol_map["exit"]];
  EXPECT_EQ(sym->st_value, 16 * 4);
  EXPECT_EQ(ELF_ST_BIND(sym->st_info), STB_LOCAL);
  EXPECT_EQ(sym->st_shndx, elf().sections[".text"]->get_index());
  EXPECT_EQ(ELF_ST_TYPE(sym->st_info), STT_NOTYPE);
  // Verify that hello is global and located in the data section at 0x2000.
  symbols.get_symbol("hello", value, size, bind, type, section_index, other);
  sym = &symspan[symbol_map["hello"]];
  EXPECT_EQ(sym->st_value, 0);
  EXPECT_EQ(sym->st_shndx, elf().sections[".data"]->get_index());
  EXPECT_EQ(ELF_ST_BIND(sym->st_info), STB_GLOBAL);
  EXPECT_EQ(ELF_ST_TYPE(sym->st_info), STT_NOTYPE);
  // Verify that semihost_param is global and located in the bss section at
  // 16 bytes.
  sym = &symspan[symbol_map["semihost_param"]];
  EXPECT_EQ(sym->st_value, 16);
  EXPECT_EQ(sym->st_shndx, elf().sections[".bss"]->get_index());
  EXPECT_EQ(ELF_ST_BIND(sym->st_info), STB_LOCAL);
  EXPECT_EQ(ELF_ST_TYPE(sym->st_info), STT_NOTYPE);
  delete string_accessor;
}

TEST_F(RiscV64XAssemblerTest, ExecutableSymbols) {
  auto status = assembler()->CreateExecutable(0x1000, "main");
  CHECK_OK(status) << status.message();
  auto* symtab = elf().sections[".symtab"];
  ELFIO::symbol_section_accessor symbols(elf(), symtab);
  ELFIO::Elf64_Addr value;
  ELFIO::Elf_Xword size;
  unsigned char bind;
  unsigned char type;
  ELFIO::Elf_Half section_index;
  unsigned char other;
  // Verify that main is valued 0x1000, global and located in the text section.
  symbols.get_symbol("main", value, size, bind, type, section_index, other);
  EXPECT_EQ(value, 0x1000);
  EXPECT_EQ(section_index, elf().sections[".text"]->get_index());
  EXPECT_EQ(type, STT_NOTYPE);
  // Verify that exit is valued 0x1000 + 16 * 4, local and located in the text
  // section.
  symbols.get_symbol("exit", value, size, bind, type, section_index, other);
  EXPECT_EQ(value, 0x1000 + 16 * 4);
  EXPECT_EQ(bind, STB_LOCAL);
  EXPECT_EQ(section_index, elf().sections[".text"]->get_index());
  EXPECT_EQ(type, STT_NOTYPE);
  // Verify that hello is global and located in the data section at 0x2000.
  symbols.get_symbol("hello", value, size, bind, type, section_index, other);
  EXPECT_EQ(value, 0x2000);
  EXPECT_EQ(section_index, elf().sections[".data"]->get_index());
  EXPECT_EQ(bind, STB_GLOBAL);
  EXPECT_EQ(type, STT_NOTYPE);
  // Verify that semihost_param is global and located in the bss section at
  // 0x2000 + 14 + alignment to 16 byte boundary, plus 16 bytes.
  symbols.get_symbol("semihost_param", value, size, bind, type, section_index,
                     other);
  EXPECT_EQ(value, 0x2000 + 16 + 16);
  EXPECT_EQ(section_index, elf().sections[".bss"]->get_index());
  EXPECT_EQ(bind, STB_LOCAL);
  EXPECT_EQ(type, STT_NOTYPE);
}

// Verify that the first 16 instructions were assembled correctly.
TEST_F(RiscV64XAssemblerTest, ExecutableTextContent) {
  auto status = assembler()->CreateExecutable(0x1000, "main");
  CHECK_OK(status) << status.message();
  auto* text = elf().sections[".text"];
  auto* data = text->get_data();
  auto* word_data = reinterpret_cast<const uint32_t*>(data);
  // Verify the first 16 instructions.
  EXPECT_EQ(word_data[0], 0x00500513);   // addi a0, zero, 5
  EXPECT_EQ(word_data[1], 0x000025b7);   // lui a1, semihost_param
  EXPECT_EQ(word_data[2], 0x02058593);   // addi a1, a1, semihost_param
  EXPECT_EQ(word_data[3], 0x00200293);   // addi t0, zero, 2
  EXPECT_EQ(word_data[4], 0x0055b023);   // sd t0, 0(a1)
  EXPECT_EQ(word_data[5], 0x000023b7);   // lui t2, hello
  EXPECT_EQ(word_data[6], 0x00038393);   // addi t2, t2, hello
  EXPECT_EQ(word_data[7], 0x0075b423);   // sd t2, 8(a1)
  EXPECT_EQ(word_data[8], 0x00c00293);   // addi t0, zero, 12
  EXPECT_EQ(word_data[9], 0x0055b823);   // sd t0, 0x10(a1)
  EXPECT_EQ(word_data[10], 0x01c000ef);  // jal ra, semihost
  EXPECT_EQ(word_data[11], 0x01800513);  // addi a0, zero, 24
  EXPECT_EQ(word_data[12], 0x000202b7);  // lui t0, 0x20026
  EXPECT_EQ(word_data[13], 0x02628293);  // addi t0, t0, 0x20026
  EXPECT_EQ(word_data[14], 0x0055b023);  // sd t0, 0(a1)
  EXPECT_EQ(word_data[15], 0x008000ef);  // jal ra, semihost
}

// Verify that the first 16 instructions were assembled correctly.
TEST_F(RiscV64XAssemblerTest, RelocatableTextContent) {
  auto status = assembler()->CreateRelocatable();
  CHECK_OK(status) << status.message();
  auto* text = elf().sections[".text"];
  auto* data = text->get_data();
  auto* word_data = reinterpret_cast<const uint32_t*>(data);
  // Verify the first 16 instructions. These will be slightly different from
  // the executable version since the symbol values are not relocated to their
  // final memory values.
  EXPECT_EQ(word_data[0], 0x00500513);   // addi a0, zero, 5
  EXPECT_EQ(word_data[1], 0x000005b7);   // lui a1, semihost_param
  EXPECT_EQ(word_data[2], 0x01058593);   // addi a1, a1, semihost_param
  EXPECT_EQ(word_data[3], 0x00200293);   // addi t0, zero, 2
  EXPECT_EQ(word_data[4], 0x0055b023);   // sd t0, 0(a1)
  EXPECT_EQ(word_data[5], 0x000003b7);   // lui t2, hello
  EXPECT_EQ(word_data[6], 0x00038393);   // addi t2, t2, hello
  EXPECT_EQ(word_data[7], 0x0075b423);   // sd t2, 8(a1)
  EXPECT_EQ(word_data[8], 0x00c00293);   // addi t0, zero, 12
  EXPECT_EQ(word_data[9], 0x0055b823);   // sd t0, 0x10(a1)
  EXPECT_EQ(word_data[10], 0x01c000ef);  // jal ra, semihost
  EXPECT_EQ(word_data[11], 0x01800513);  // addi a0, zero, 24
  EXPECT_EQ(word_data[12], 0x000202b7);  // lui t0, 0x20026
  EXPECT_EQ(word_data[13], 0x02628293);  // addi t0, t0, 0x20026
  EXPECT_EQ(word_data[14], 0x0055b023);  // sd t0, 0(a1)
  EXPECT_EQ(word_data[15], 0x008000ef);  // jal ra, semihost
}

TEST_F(RiscV64XAssemblerTest, TextRelocations) {
  auto status = assembler()->CreateRelocatable();
  CHECK_OK(status) << status.message();
  auto* rela_section = elf().sections[".rela.text"];
  EXPECT_NE(rela_section, nullptr);
  auto* rela_data = rela_section->get_data();
  auto rela =
      absl::MakeSpan(reinterpret_cast<const ELFIO::Elf64_Rela*>(rela_data),
                     rela_section->get_size() / sizeof(ELFIO::Elf64_Rela));
  EXPECT_EQ(rela.size(), 4);
}

}  // namespace
