//===-- 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::DataExtractorSP &extractor_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;
}
