//===-- 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::DataBufferSP data_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;
}
