//===-- ObjectFileJSON.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "Plugins/ObjectFile/JSON/ObjectFileJSON.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringExtras.h"
#include <optional>

using namespace llvm;
using namespace lldb;
using namespace lldb_private;

LLDB_PLUGIN_DEFINE(ObjectFileJSON)

char ObjectFileJSON::ID;

/// Returns the JSON text in the buffer, which is not NULL terminated and may
/// be zero padded past the end of the file.
static StringRef GetText(const lldb_private::DataExtractor &data) {
  StringRef text = toStringRef(data.GetData());
  return text.substr(0, text.find('\0'));
}

void ObjectFileJSON::Initialize() {
  PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                GetPluginDescriptionStatic(), CreateInstance,
                                CreateMemoryInstance, GetModuleSpecifications);
}

void ObjectFileJSON::Terminate() {
  PluginManager::UnregisterPlugin(CreateInstance);
}

ObjectFile *ObjectFileJSON::CreateInstance(const ModuleSP &module_sp,
                                           DataExtractorSP extractor_sp,
                                           offset_t data_offset,
                                           const FileSpec *file,
                                           offset_t file_offset,
                                           offset_t length) {
  if (!extractor_sp || !extractor_sp->HasData()) {
    DataBufferSP data_sp = MapFileData(*file, length, file_offset);
    if (!data_sp)
      return nullptr;
    extractor_sp = std::make_shared<DataExtractor>(data_sp);
    data_offset = 0;
  }
  if (!extractor_sp->HasData())
    return nullptr;

  if (!MagicBytesMatch(extractor_sp->GetSubsetExtractorSP(data_offset)))
    return nullptr;

  // Update the data to contain the entire file if it doesn't already.
  if (extractor_sp->GetByteSize() < length) {
    DataBufferSP data_sp = MapFileData(*file, length, file_offset);
    if (!data_sp)
      return nullptr;
    extractor_sp->SetData(data_sp);
    data_offset = 0;
  }

  Log *log = GetLog(LLDBLog::Symbols);

  StringRef text = GetText(*extractor_sp);

  Expected<json::Value> json = json::parse(text);
  if (!json) {
    LLDB_LOG_ERROR(log, json.takeError(),
                   "failed to parse JSON object file: {0}");
    return nullptr;
  }

  json::Path::Root root;
  Header header;
  if (!fromJSON(*json, header, root)) {
    LLDB_LOG_ERROR(log, root.getError(),
                   "failed to parse JSON object file header: {0}");
    return nullptr;
  }

  ArchSpec arch(header.triple);
  UUID uuid;
  uuid.SetFromStringRef(header.uuid);
  Type type = header.type.value_or(eTypeDebugInfo);

  Body body;
  if (!fromJSON(*json, body, root)) {
    LLDB_LOG_ERROR(log, root.getError(),
                   "failed to parse JSON object file body: {0}");
    return nullptr;
  }

  return new ObjectFileJSON(module_sp, extractor_sp, data_offset, file,
                            file_offset, length, std::move(arch),
                            std::move(uuid), type, std::move(body.symbols),
                            std::move(body.sections));
}

ObjectFile *ObjectFileJSON::CreateMemoryInstance(const ModuleSP &module_sp,
                                                 WritableDataBufferSP data_sp,
                                                 const ProcessSP &process_sp,
                                                 addr_t header_addr) {
  return nullptr;
}

ModuleSpecList
ObjectFileJSON::GetModuleSpecifications(const FileSpec &file,
                                        DataExtractorSP &extractor_sp,
                                        offset_t file_offset, offset_t length) {
  if (!extractor_sp || !MagicBytesMatch(extractor_sp))
    return {};

  // Update the data to contain the entire file if it doesn't already.
  if (extractor_sp->GetByteSize() < length) {
    if (DataBufferSP file_data_sp = MapFileData(file, length, file_offset))
      extractor_sp->SetData(file_data_sp);
    if (!extractor_sp->HasData())
      return {};
  }

  Log *log = GetLog(LLDBLog::Symbols);

  StringRef text = GetText(*extractor_sp);

  Expected<json::Value> json = json::parse(text);
  if (!json) {
    LLDB_LOG_ERROR(log, json.takeError(),
                   "failed to parse JSON object file: {0}");
    return {};
  }

  json::Path::Root root;
  Header header;
  if (!fromJSON(*json, header, root)) {
    LLDB_LOG_ERROR(log, root.getError(),
                   "failed to parse JSON object file header: {0}");
    return {};
  }

  ArchSpec arch(header.triple);
  UUID uuid;
  uuid.SetFromStringRef(header.uuid);

  ModuleSpec spec(file, std::move(arch));
  spec.GetUUID() = std::move(uuid);
  ModuleSpecList specs;
  specs.Append(spec);
  return specs;
}

ObjectFileJSON::ObjectFileJSON(const ModuleSP &module_sp,
                               DataExtractorSP extractor_sp,
                               offset_t data_offset, const FileSpec *file,
                               offset_t offset, offset_t length, ArchSpec arch,
                               UUID uuid, Type type,
                               std::vector<JSONSymbol> symbols,
                               std::vector<JSONSection> sections)
    : ObjectFile(module_sp, file, offset, length, extractor_sp, data_offset),
      m_arch(std::move(arch)), m_uuid(std::move(uuid)), m_type(type),
      m_symbols(std::move(symbols)), m_sections(std::move(sections)) {}

bool ObjectFileJSON::ParseHeader() {
  // We already parsed the header during initialization.
  return true;
}

void ObjectFileJSON::ParseSymtab(Symtab &symtab) {
  Log *log = GetLog(LLDBLog::Symbols);
  SectionList *section_list = GetModule()->GetSectionList();
  for (JSONSymbol json_symbol : m_symbols) {
    llvm::Expected<Symbol> symbol = Symbol::FromJSON(json_symbol, section_list);
    if (!symbol) {
      LLDB_LOG_ERROR(log, symbol.takeError(), "invalid symbol: {0}");
      continue;
    }
    symtab.AddSymbol(*symbol);
  }
  symtab.Finalize();
}

void ObjectFileJSON::CreateSections(SectionList &unified_section_list) {
  if (m_sections_up)
    return;
  m_sections_up = std::make_unique<SectionList>();

  lldb::user_id_t id = 0;
  for (const auto &json_section : m_sections) {
    auto make_section = [this, &id](const JSONSection &section,
                                    SectionSP parent_section_sp =
                                        nullptr) -> SectionSP {
      SectionSP section_sp;
      auto sect_id = section.user_id.value_or(id + 1);
      if (!section.user_id.has_value())
        ++id;
      const auto name = ConstString(section.name);
      const auto sect_type = section.type.value_or(eSectionTypeCode);
      const auto vm_addr = section.address.value_or(0);
      const auto vm_size = section.size.value_or(0);
      const auto file_offset = section.file_offset.value_or(0);
      const auto file_size = section.file_size.value_or(0);
      const auto log2align = section.log2align.value_or(0);
      const auto flags = section.flags.value_or(0);
      if (parent_section_sp) {
        section_sp = std::make_shared<Section>(
            parent_section_sp, GetModule(), this, sect_id, name, sect_type,
            vm_addr - parent_section_sp->GetFileAddress(), vm_size, file_offset,
            file_size, log2align, flags);

      } else {
        section_sp = std::make_shared<Section>(
            GetModule(), this, sect_id, name, sect_type, vm_addr, vm_size,
            file_offset, file_size, log2align, flags);
      }
      // Set permissions
      uint32_t permissions = 0;
      if (section.read.value_or(0))
        permissions |= lldb::ePermissionsReadable;
      if (section.write.value_or(0))
        permissions |= lldb::ePermissionsWritable;
      if (section.execute.value_or(0))
        permissions |= lldb::ePermissionsExecutable;
      if (permissions)
        section_sp->SetPermissions(permissions);
      section_sp->SetIsFake(section.fake.value_or(false));
      section_sp->SetIsEncrypted(section.encrypted.value_or(false));
      section_sp->SetIsThreadSpecific(section.thread_specific.value_or(false));
      return section_sp;
    };
    auto section_sp = make_section(json_section);
    for (const auto &subsection : json_section.subsections) {
      SectionSP subsection_sp = make_section(subsection, section_sp);
      section_sp->GetChildren().AddSection(subsection_sp);
    }

    m_sections_up->AddSection(section_sp);
    unified_section_list.AddSection(section_sp);
  }
}

bool ObjectFileJSON::SetLoadAddress(Target &target, lldb::addr_t value,
                                    bool value_is_offset) {
  Log *log(GetLog(LLDBLog::DynamicLoader));
  if (!m_sections_up)
    return true;

  addr_t slide = value;
  if (!value_is_offset) {
    addr_t lowest_addr = LLDB_INVALID_ADDRESS;
    for (const SectionSP &section_sp : *m_sections_up) {
      addr_t section_load_addr = section_sp->GetFileAddress();
      lowest_addr = std::min(lowest_addr, section_load_addr);
    }
    if (lowest_addr == LLDB_INVALID_ADDRESS)
      return false;
    slide = value - lowest_addr;
  }

  // Apply slide to each section's file address.
  for (const SectionSP &section_sp : *m_sections_up) {
    addr_t section_load_addr = section_sp->GetFileAddress();
    if (section_load_addr != LLDB_INVALID_ADDRESS) {
      LLDB_LOG(log,
               "ObjectFileJSON::SetLoadAddress section {0} to load addr {1:x}",
               section_sp->GetName(), section_load_addr + slide);
      target.SetSectionLoadAddress(section_sp, section_load_addr + slide,
                                   /*warn_multiple=*/true);
    }
  }

  return true;
}

bool ObjectFileJSON::MagicBytesMatch(DataExtractorSP extractor_sp) {
  lldb::offset_t offset = 0;
  char magic = extractor_sp->GetU8(&offset);
  return magic == '{';
}

namespace lldb_private {

bool fromJSON(const json::Value &value, ObjectFileJSON::Header &header,
              json::Path path) {
  json::ObjectMapper o(value, path);
  return o && o.map("triple", header.triple) && o.map("uuid", header.uuid) &&
         o.map("type", header.type);
}

bool fromJSON(const json::Value &value, ObjectFileJSON::Body &body,
              json::Path path) {
  json::ObjectMapper o(value, path);
  return o && o.mapOptional("symbols", body.symbols) &&
         o.mapOptional("sections", body.sections);
}

} // namespace lldb_private
