//===- 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 "Reproducer.h"
#include "llvm/Support/Path.h"

using namespace llvm;
using namespace llvm::dsymutil;

static std::string createReproducerDir(std::error_code &EC) {
  SmallString<128> Root;
  if (const char *Path = getenv("DSYMUTIL_REPRODUCER_PATH")) {
    Root.assign(Path);
    EC = sys::fs::create_directory(Root);
  } else {
    EC = sys::fs::createUniqueDirectory("dsymutil", Root);
  }
  return EC ? "" : std::string(Root);
}

Reproducer::Reproducer() : VFS(vfs::getRealFileSystem()) {}
Reproducer::~Reproducer() = default;

ReproducerGenerate::ReproducerGenerate(std::error_code &EC, int Argc,
                                       char **Argv, bool GenerateOnExit)
    : Root(createReproducerDir(EC)), GenerateOnExit(GenerateOnExit) {
  for (int I = 0; I < Argc; ++I)
    Args.push_back(Argv[I]);
  if (!Root.empty())
    FC = std::make_shared<FileCollector>(Root, Root);
  VFS = FileCollector::createCollectorVFS(vfs::getRealFileSystem(), FC);
}

ReproducerGenerate::~ReproducerGenerate() {
  if (GenerateOnExit && !Generated)
    generate();
}

void ReproducerGenerate::generate() {
  if (!FC)
    return;
  Generated = true;
  FC->copyFiles(false);
  SmallString<128> Mapping(Root);
  sys::path::append(Mapping, "mapping.yaml");
  FC->writeMapping(Mapping.str());
  errs() << "********************\n";
  errs() << "Reproducer written to " << Root << '\n';
  errs() << "Please include the reproducer and the following invocation in "
            "your bug report:\n";
  for (llvm::StringRef Arg : Args)
    errs() << Arg << ' ';
  errs() << "--use-reproducer " << Root << '\n';
  errs() << "********************\n";
}

ReproducerUse::~ReproducerUse() = default;

ReproducerUse::ReproducerUse(StringRef Root, std::error_code &EC) {
  SmallString<128> Mapping(Root);
  sys::path::append(Mapping, "mapping.yaml");
  ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
      vfs::getRealFileSystem()->getBufferForFile(Mapping.str());

  if (!Buffer) {
    EC = Buffer.getError();
    return;
  }

  VFS = llvm::vfs::getVFSFromYAML(std::move(Buffer.get()), nullptr, Mapping);
}

llvm::Expected<std::unique_ptr<Reproducer>>
Reproducer::createReproducer(ReproducerMode Mode, StringRef Root, int Argc,
                             char **Argv) {

  std::error_code EC;
  std::unique_ptr<Reproducer> Repro;
  switch (Mode) {
  case ReproducerMode::GenerateOnExit:
    Repro = std::make_unique<ReproducerGenerate>(EC, Argc, Argv, true);
    break;
  case ReproducerMode::GenerateOnCrash:
    Repro = std::make_unique<ReproducerGenerate>(EC, Argc, Argv, false);
    break;
  case ReproducerMode::Use:
    Repro = std::make_unique<ReproducerUse>(Root, EC);
    break;
  case ReproducerMode::Off:
    Repro = std::make_unique<Reproducer>();
    break;
  }
  if (EC)
    return errorCodeToError(EC);
  return {std::move(Repro)};
}
