//===-- Reproducer.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 "lldb/Utility/ReproducerProvider.h"
#include "lldb/Utility/ProcessInfo.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"

using namespace lldb_private;
using namespace lldb_private::repro;
using namespace llvm;
using namespace llvm::yaml;

llvm::Expected<std::unique_ptr<DataRecorder>>
DataRecorder::Create(const FileSpec &filename) {
  std::error_code ec;
  auto recorder = std::make_unique<DataRecorder>(std::move(filename), ec);
  if (ec)
    return llvm::errorCodeToError(ec);
  return std::move(recorder);
}

llvm::Expected<std::unique_ptr<YamlRecorder>>
YamlRecorder::Create(const FileSpec &filename) {
  std::error_code ec;
  auto recorder = std::make_unique<YamlRecorder>(std::move(filename), ec);
  if (ec)
    return llvm::errorCodeToError(ec);
  return std::move(recorder);
}

void VersionProvider::Keep() {
  FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file);
  std::error_code ec;
  llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
  if (ec)
    return;
  os << m_version << "\n";
}

FlushingFileCollector::FlushingFileCollector(llvm::StringRef files_path,
                                             llvm::StringRef dirs_path,
                                             std::error_code &ec) {
  auto clear = llvm::make_scope_exit([this]() {
    m_files_os.reset();
    m_dirs_os.reset();
  });
  m_files_os.emplace(files_path, ec, llvm::sys::fs::OF_Append);
  if (ec)
    return;
  m_dirs_os.emplace(dirs_path, ec, llvm::sys::fs::OF_Append);
  if (ec)
    return;
  clear.release();
}

void FlushingFileCollector::addFileImpl(StringRef file) {
  if (m_files_os) {
    *m_files_os << file << '\0';
    m_files_os->flush();
  }
}

llvm::vfs::directory_iterator
FlushingFileCollector::addDirectoryImpl(const Twine &dir,
                                        IntrusiveRefCntPtr<vfs::FileSystem> vfs,
                                        std::error_code &dir_ec) {
  if (m_dirs_os) {
    *m_dirs_os << dir << '\0';
    m_dirs_os->flush();
  }
  return vfs->dir_begin(dir, dir_ec);
}

void FileProvider::RecordInterestingDirectory(const llvm::Twine &dir) {
  if (m_collector)
    m_collector->addFile(dir);
}

void FileProvider::RecordInterestingDirectoryRecursive(const llvm::Twine &dir) {
  if (m_collector)
    m_collector->addDirectory(dir);
}

llvm::Expected<std::unique_ptr<ProcessInfoRecorder>>
ProcessInfoRecorder::Create(const FileSpec &filename) {
  std::error_code ec;
  auto recorder =
      std::make_unique<ProcessInfoRecorder>(std::move(filename), ec);
  if (ec)
    return llvm::errorCodeToError(ec);
  return std::move(recorder);
}

void ProcessInfoProvider::Keep() {
  std::vector<std::string> files;
  for (auto &recorder : m_process_info_recorders) {
    recorder->Stop();
    files.push_back(recorder->GetFilename().GetPath());
  }

  FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file);
  std::error_code ec;
  llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
  if (ec)
    return;
  llvm::yaml::Output yout(os);
  yout << files;
}

void ProcessInfoProvider::Discard() { m_process_info_recorders.clear(); }

ProcessInfoRecorder *ProcessInfoProvider::GetNewProcessInfoRecorder() {
  std::size_t i = m_process_info_recorders.size() + 1;
  std::string filename = (llvm::Twine(Info::name) + llvm::Twine("-") +
                          llvm::Twine(i) + llvm::Twine(".yaml"))
                             .str();
  auto recorder_or_error = ProcessInfoRecorder::Create(
      GetRoot().CopyByAppendingPathComponent(filename));
  if (!recorder_or_error) {
    llvm::consumeError(recorder_or_error.takeError());
    return nullptr;
  }

  m_process_info_recorders.push_back(std::move(*recorder_or_error));
  return m_process_info_recorders.back().get();
}

void ProcessInfoRecorder::Record(const ProcessInstanceInfoList &process_infos) {
  if (!m_record)
    return;
  llvm::yaml::Output yout(m_os);
  yout << const_cast<ProcessInstanceInfoList &>(process_infos);
  m_os.flush();
}

void SymbolFileProvider::AddSymbolFile(const UUID *uuid,
                                       const FileSpec &module_file,
                                       const FileSpec &symbol_file) {
  if (!uuid || (!module_file && !symbol_file))
    return;
  m_symbol_files.emplace_back(uuid->GetAsString(), module_file.GetPath(),
                              symbol_file.GetPath());
}

void SymbolFileProvider::Keep() {
  FileSpec file = this->GetRoot().CopyByAppendingPathComponent(Info::file);
  std::error_code ec;
  llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
  if (ec)
    return;

  // Remove duplicates.
  llvm::sort(m_symbol_files.begin(), m_symbol_files.end());
  m_symbol_files.erase(
      std::unique(m_symbol_files.begin(), m_symbol_files.end()),
      m_symbol_files.end());

  llvm::yaml::Output yout(os);
  yout << m_symbol_files;
}

SymbolFileLoader::SymbolFileLoader(Loader *loader) {
  if (!loader)
    return;

  FileSpec file = loader->GetFile<SymbolFileProvider::Info>();
  if (!file)
    return;

  auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath());
  if (auto err = error_or_file.getError())
    return;

  llvm::yaml::Input yin((*error_or_file)->getBuffer());
  yin >> m_symbol_files;
}

std::pair<FileSpec, FileSpec>
SymbolFileLoader::GetPaths(const UUID *uuid) const {
  if (!uuid)
    return {};

  auto it = std::lower_bound(m_symbol_files.begin(), m_symbol_files.end(),
                             SymbolFileProvider::Entry(uuid->GetAsString()));
  if (it == m_symbol_files.end())
    return {};
  return std::make_pair<FileSpec, FileSpec>(FileSpec(it->module_path),
                                            FileSpec(it->symbol_path));
}

void ProviderBase::anchor() {}
char CommandProvider::ID = 0;
char FileProvider::ID = 0;
char ProviderBase::ID = 0;
char VersionProvider::ID = 0;
char WorkingDirectoryProvider::ID = 0;
char HomeDirectoryProvider::ID = 0;
char ProcessInfoProvider::ID = 0;
char SymbolFileProvider::ID = 0;
const char *CommandProvider::Info::file = "command-interpreter.yaml";
const char *CommandProvider::Info::name = "command-interpreter";
const char *FileProvider::Info::file = "files.yaml";
const char *FileProvider::Info::name = "files";
const char *VersionProvider::Info::file = "version.txt";
const char *VersionProvider::Info::name = "version";
const char *WorkingDirectoryProvider::Info::file = "cwd.txt";
const char *WorkingDirectoryProvider::Info::name = "cwd";
const char *HomeDirectoryProvider::Info::file = "home.txt";
const char *HomeDirectoryProvider::Info::name = "home";
const char *ProcessInfoProvider::Info::file = "process-info.yaml";
const char *ProcessInfoProvider::Info::name = "process-info";
const char *SymbolFileProvider::Info::file = "symbol-files.yaml";
const char *SymbolFileProvider::Info::name = "symbol-files";
