//===-- cc1gen_reproducer_main.cpp - Clang reproducer generator  ----------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This is the entry point to the clang -cc1gen-reproducer functionality, which
// generates reproducers for invocations for clang-based tools.
//
//===----------------------------------------------------------------------===//

#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"

using namespace clang;

namespace {

struct UnsavedFileHash {
  std::string Name;
  std::string MD5;
};

struct ClangInvocationInfo {
  std::string Toolchain;
  std::string LibclangOperation;
  std::string LibclangOptions;
  std::vector<std::string> Arguments;
  std::vector<std::string> InvocationArguments;
  std::vector<UnsavedFileHash> UnsavedFileHashes;
  bool Dump = false;
};

} // end anonymous namespace

LLVM_YAML_IS_SEQUENCE_VECTOR(UnsavedFileHash)

namespace llvm {
namespace yaml {

template <> struct MappingTraits<UnsavedFileHash> {
  static void mapping(IO &IO, UnsavedFileHash &Info) {
    IO.mapRequired("name", Info.Name);
    IO.mapRequired("md5", Info.MD5);
  }
};

template <> struct MappingTraits<ClangInvocationInfo> {
  static void mapping(IO &IO, ClangInvocationInfo &Info) {
    IO.mapRequired("toolchain", Info.Toolchain);
    IO.mapOptional("libclang.operation", Info.LibclangOperation);
    IO.mapOptional("libclang.opts", Info.LibclangOptions);
    IO.mapRequired("args", Info.Arguments);
    IO.mapOptional("invocation-args", Info.InvocationArguments);
    IO.mapOptional("unsaved_file_hashes", Info.UnsavedFileHashes);
  }
};

} // end namespace yaml
} // end namespace llvm

static std::string generateReproducerMetaInfo(const ClangInvocationInfo &Info) {
  std::string Result;
  llvm::raw_string_ostream OS(Result);
  OS << '{';
  bool NeedComma = false;
  auto EmitKey = [&](StringRef Key) {
    if (NeedComma)
      OS << ", ";
    NeedComma = true;
    OS << '"' << Key << "\": ";
  };
  auto EmitStringKey = [&](StringRef Key, StringRef Value) {
    if (Value.empty())
      return;
    EmitKey(Key);
    OS << '"' << Value << '"';
  };
  EmitStringKey("libclang.operation", Info.LibclangOperation);
  EmitStringKey("libclang.opts", Info.LibclangOptions);
  if (!Info.InvocationArguments.empty()) {
    EmitKey("invocation-args");
    OS << '[';
    for (const auto &Arg : llvm::enumerate(Info.InvocationArguments)) {
      if (Arg.index())
        OS << ',';
      OS << '"' << Arg.value() << '"';
    }
    OS << ']';
  }
  OS << '}';
  // FIXME: Compare unsaved file hashes and report mismatch in the reproducer.
  if (Info.Dump)
    llvm::outs() << "REPRODUCER METAINFO: " << OS.str() << "\n";
  return std::move(OS.str());
}

/// Generates a reproducer for a set of arguments from a specific invocation.
static llvm::Optional<driver::Driver::CompilationDiagnosticReport>
generateReproducerForInvocationArguments(ArrayRef<const char *> Argv,
                                         const ClangInvocationInfo &Info) {
  using namespace driver;
  auto TargetAndMode = ToolChain::getTargetAndModeFromProgramName(Argv[0]);

  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions;

  IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
  DiagnosticsEngine Diags(DiagID, &*DiagOpts, new IgnoringDiagConsumer());
  ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);
  Driver TheDriver(Argv[0], llvm::sys::getDefaultTargetTriple(), Diags);
  TheDriver.setTargetAndMode(TargetAndMode);

  std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(Argv));
  if (C && !C->containsError()) {
    for (const auto &J : C->getJobs()) {
      if (const Command *Cmd = dyn_cast<Command>(&J)) {
        Driver::CompilationDiagnosticReport Report;
        TheDriver.generateCompilationDiagnostics(
            *C, *Cmd, generateReproducerMetaInfo(Info), &Report);
        return Report;
      }
    }
  }

  return None;
}

std::string GetExecutablePath(const char *Argv0, bool CanonicalPrefixes);

static void printReproducerInformation(
    llvm::raw_ostream &OS, const ClangInvocationInfo &Info,
    const driver::Driver::CompilationDiagnosticReport &Report) {
  OS << "REPRODUCER:\n";
  OS << "{\n";
  OS << R"("files":[)";
  for (const auto &File : llvm::enumerate(Report.TemporaryFiles)) {
    if (File.index())
      OS << ',';
    OS << '"' << File.value() << '"';
  }
  OS << "]\n}\n";
}

int cc1gen_reproducer_main(ArrayRef<const char *> Argv, const char *Argv0,
                           void *MainAddr) {
  if (Argv.size() < 1) {
    llvm::errs() << "error: missing invocation file\n";
    return 1;
  }
  // Parse the invocation descriptor.
  StringRef Input = Argv[0];
  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
      llvm::MemoryBuffer::getFile(Input);
  if (!Buffer) {
    llvm::errs() << "error: failed to read " << Input << ": "
                 << Buffer.getError().message() << "\n";
    return 1;
  }
  llvm::yaml::Input YAML(Buffer.get()->getBuffer());
  ClangInvocationInfo InvocationInfo;
  YAML >> InvocationInfo;
  if (Argv.size() > 1 && Argv[1] == StringRef("-v"))
    InvocationInfo.Dump = true;

  // Create an invocation that will produce the reproducer.
  std::vector<const char *> DriverArgs;
  for (const auto &Arg : InvocationInfo.Arguments)
    DriverArgs.push_back(Arg.c_str());
  std::string Path = GetExecutablePath(Argv0, /*CanonicalPrefixes=*/true);
  DriverArgs[0] = Path.c_str();
  llvm::Optional<driver::Driver::CompilationDiagnosticReport> Report =
      generateReproducerForInvocationArguments(DriverArgs, InvocationInfo);

  // Emit the information about the reproduce files to stdout.
  int Result = 1;
  if (Report) {
    printReproducerInformation(llvm::outs(), InvocationInfo, *Report);
    Result = 0;
  }

  // Remove the input file.
  llvm::sys::fs::remove(Input);
  return Result;
}
