//===-- ObjectFileBreakpad.cpp -------------------------------- -*- C++ -*-===//
//
// 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/Breakpad/ObjectFileBreakpad.h"
#include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::breakpad;

namespace {
struct Header {
  ArchSpec arch;
  UUID uuid;
  static llvm::Optional<Header> parse(llvm::StringRef text);
};
} // namespace

llvm::Optional<Header> Header::parse(llvm::StringRef text) {
  llvm::StringRef line;
  std::tie(line, text) = text.split('\n');
  auto Module = ModuleRecord::parse(line);
  if (!Module)
    return llvm::None;

  llvm::Triple triple;
  triple.setArch(Module->Arch);
  triple.setOS(Module->OS);

  std::tie(line, text) = text.split('\n');

  auto Info = InfoRecord::parse(line);
  UUID uuid = Info && Info->ID ? Info->ID : Module->ID;
  return Header{ArchSpec(triple), std::move(uuid)};
}

char ObjectFileBreakpad::ID;

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

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

ConstString ObjectFileBreakpad::GetPluginNameStatic() {
  static ConstString g_name("breakpad");
  return g_name;
}

ObjectFile *ObjectFileBreakpad::CreateInstance(
    const ModuleSP &module_sp, DataBufferSP &data_sp, offset_t data_offset,
    const FileSpec *file, offset_t file_offset, offset_t length) {
  if (!data_sp) {
    data_sp = MapFileData(*file, length, file_offset);
    if (!data_sp)
      return nullptr;
    data_offset = 0;
  }
  auto text = toStringRef(data_sp->GetData());
  llvm::Optional<Header> header = Header::parse(text);
  if (!header)
    return nullptr;

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

  return new ObjectFileBreakpad(module_sp, data_sp, data_offset, file,
                                file_offset, length, std::move(header->arch),
                                std::move(header->uuid));
}

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

size_t ObjectFileBreakpad::GetModuleSpecifications(
    const FileSpec &file, DataBufferSP &data_sp, offset_t data_offset,
    offset_t file_offset, offset_t length, ModuleSpecList &specs) {
  auto text = toStringRef(data_sp->GetData());
  llvm::Optional<Header> header = Header::parse(text);
  if (!header)
    return 0;
  ModuleSpec spec(file, std::move(header->arch));
  spec.GetUUID() = std::move(header->uuid);
  specs.Append(spec);
  return 1;
}

ObjectFileBreakpad::ObjectFileBreakpad(const ModuleSP &module_sp,
                                       DataBufferSP &data_sp,
                                       offset_t data_offset,
                                       const FileSpec *file, offset_t offset,
                                       offset_t length, ArchSpec arch,
                                       UUID uuid)
    : ObjectFile(module_sp, file, offset, length, data_sp, data_offset),
      m_arch(std::move(arch)), m_uuid(std::move(uuid)) {}

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

Symtab *ObjectFileBreakpad::GetSymtab() {
  // TODO
  return nullptr;
}

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

  llvm::Optional<Record::Kind> current_section;
  offset_t section_start;
  llvm::StringRef text = toStringRef(m_data.GetData());
  uint32_t next_section_id = 1;
  auto maybe_add_section = [&](const uint8_t *end_ptr) {
    if (!current_section)
      return; // We have been called before parsing the first line.

    offset_t end_offset = end_ptr - m_data.GetDataStart();
    auto section_sp = std::make_shared<Section>(
        GetModule(), this, next_section_id++,
        ConstString(toString(*current_section)), eSectionTypeOther,
        /*file_vm_addr*/ 0, /*vm_size*/ 0, section_start,
        end_offset - section_start, /*log2align*/ 0, /*flags*/ 0);
    m_sections_up->AddSection(section_sp);
    unified_section_list.AddSection(section_sp);
  };
  while (!text.empty()) {
    llvm::StringRef line;
    std::tie(line, text) = text.split('\n');

    llvm::Optional<Record::Kind> next_section = Record::classify(line);
    if (next_section == Record::Line) {
      // Line records logically belong to the preceding Func record, so we put
      // them in the same section.
      next_section = Record::Func;
    }
    if (next_section == current_section)
      continue;

    // Changing sections, finish off the previous one, if there was any.
    maybe_add_section(line.bytes_begin());
    // And start a new one.
    current_section = next_section;
    section_start = line.bytes_begin() - m_data.GetDataStart();
  }
  // Finally, add the last section.
  maybe_add_section(m_data.GetDataEnd());
}
