//===-- ObjectFileMinidump.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 "ObjectFileMinidump.h"

#include "MinidumpFileBuilder.h"

#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"

#include "llvm/Support/FileSystem.h"

using namespace lldb;
using namespace lldb_private;

LLDB_PLUGIN_DEFINE(ObjectFileMinidump)

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

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

ObjectFile *ObjectFileMinidump::CreateInstance(
    const lldb::ModuleSP &module_sp, lldb::DataExtractorSP extractor_sp,
    lldb::offset_t data_offset, const lldb_private::FileSpec *file,
    lldb::offset_t offset, lldb::offset_t length) {
  return nullptr;
}

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

size_t ObjectFileMinidump::GetModuleSpecifications(
    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
    lldb::offset_t data_offset, lldb::offset_t file_offset,
    lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
  specs.Clear();
  return 0;
}

struct DumpFailRemoveHolder {
  DumpFailRemoveHolder(MinidumpFileBuilder &builder) : m_builder(builder) {}

  ~DumpFailRemoveHolder() {
    if (!m_success)
      m_builder.DeleteFile();
  }

  void SetSuccess() { m_success = true; }

private:
  MinidumpFileBuilder &m_builder;
  bool m_success = false;
};

bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP &process_sp,
                                  lldb_private::SaveCoreOptions &options,
                                  lldb_private::Status &error) {
  // Output file and process_sp are both checked in PluginManager::SaveCore.
  assert(options.GetOutputFile().has_value());
  assert(process_sp);

  // Minidump defaults to stacks only.
  if (options.GetStyle() == SaveCoreStyle::eSaveCoreUnspecified)
    options.SetStyle(SaveCoreStyle::eSaveCoreStackOnly);

  llvm::Expected<lldb::FileUP> maybe_core_file = FileSystem::Instance().Open(
      options.GetOutputFile().value(),
      File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate);
  if (!maybe_core_file) {
    error = Status::FromError(maybe_core_file.takeError());
    return false;
  }
  MinidumpFileBuilder builder(std::move(maybe_core_file.get()), process_sp,
                              options);
  DumpFailRemoveHolder request(builder);

  Log *log = GetLog(LLDBLog::Object);
  error = builder.AddHeaderAndCalculateDirectories();
  if (error.Fail()) {
    LLDB_LOGF(log, "AddHeaderAndCalculateDirectories failed: %s",
              error.AsCString());
    return false;
  };
  error = builder.AddSystemInfo();
  if (error.Fail()) {
    LLDB_LOGF(log, "AddSystemInfo failed: %s", error.AsCString());
    return false;
  }

  error = builder.AddModuleList();
  if (error.Fail()) {
    LLDB_LOGF(log, "AddModuleList failed: %s", error.AsCString());
    return false;
  }
  error = builder.AddMiscInfo();
  if (error.Fail()) {
    LLDB_LOGF(log, "AddMiscInfo failed: %s", error.AsCString());
    return false;
  }

  error = builder.AddThreadList();
  if (error.Fail()) {
    LLDB_LOGF(log, "AddThreadList failed: %s", error.AsCString());
    return false;
  }

  error = builder.AddLinuxFileStreams();
  if (error.Fail()) {
    LLDB_LOGF(log, "AddLinuxFileStreams failed: %s", error.AsCString());
    return false;
  }

  // Add any exceptions but only if there are any in any threads.
  error = builder.AddExceptions();
  if (error.Fail()) {
    LLDB_LOGF(log, "AddExceptions failed: %s", error.AsCString());
    return false;
  }

  // Note: add memory HAS to be the last thing we do. It can overflow into 64b
  // land and many RVA's only support 32b
  error = builder.AddMemoryList();
  if (error.Fail()) {
    LLDB_LOGF(log, "AddMemoryList failed: %s", error.AsCString());
    return false;
  }

  error = builder.DumpFile();
  if (error.Fail()) {
    LLDB_LOGF(log, "DumpFile failed: %s", error.AsCString());
    return false;
  }

  request.SetSuccess();

  return true;
}
