//===-- arcmt-test.cpp - ARC Migration Tool testbed -----------------------===//
//
// 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 "clang/ARCMigrate/ARCMT.h"
#include "clang/AST/ASTContext.h"
#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/Utils.h"
#include "clang/Frontend/VerifyDiagnosticConsumer.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include <system_error>

using namespace clang;
using namespace arcmt;

static llvm::cl::opt<bool>
CheckOnly("check-only",
      llvm::cl::desc("Just check for issues that need to be handled manually"));

//static llvm::cl::opt<bool>
//TestResultForARC("test-result",
//llvm::cl::desc("Test the result of transformations by parsing it in ARC mode"));

static llvm::cl::opt<bool>
OutputTransformations("output-transformations",
                      llvm::cl::desc("Print the source transformations"));

static llvm::cl::opt<bool>
VerifyDiags("verify",llvm::cl::desc("Verify emitted diagnostics and warnings"));

static llvm::cl::opt<bool>
VerboseOpt("v", llvm::cl::desc("Enable verbose output"));

static llvm::cl::opt<bool>
VerifyTransformedFiles("verify-transformed-files",
llvm::cl::desc("Read pairs of file mappings (typically the output of "
               "c-arcmt-test) and compare their contents with the filenames "
               "provided in command-line"));

static llvm::cl::opt<std::string>
RemappingsFile("remappings-file",
               llvm::cl::desc("Pairs of file mappings (typically the output of "
               "c-arcmt-test)"));

static llvm::cl::list<std::string>
ResultFiles(llvm::cl::Positional, llvm::cl::desc("<filename>..."));

static llvm::cl::extrahelp extraHelp(
  "\nusage with compiler args: arcmt-test [options] --args [compiler flags]\n");

// This function isn't referenced outside its translation unit, but it
// can't use the "static" keyword because its address is used for
// GetMainExecutable (since some platforms don't support taking the
// address of main, and some platforms can't implement GetMainExecutable
// without being given the address of a function in the main executable).
std::string GetExecutablePath(const char *Argv0) {
  // This just needs to be some symbol in the binary; C++ doesn't
  // allow taking the address of ::main however.
  void *MainAddr = (void*) (intptr_t) GetExecutablePath;
  return llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
}

static void printSourceLocation(SourceLocation loc, ASTContext &Ctx,
                                raw_ostream &OS);
static void printSourceRange(CharSourceRange range, ASTContext &Ctx,
                             raw_ostream &OS);

namespace {

class PrintTransforms : public MigrationProcess::RewriteListener {
  ASTContext *Ctx;
  raw_ostream &OS;

public:
  PrintTransforms(raw_ostream &OS)
    : Ctx(nullptr), OS(OS) {}

  void start(ASTContext &ctx) override { Ctx = &ctx; }
  void finish() override { Ctx = nullptr; }

  void insert(SourceLocation loc, StringRef text) override {
    assert(Ctx);
    OS << "Insert: ";
    printSourceLocation(loc, *Ctx, OS);
    OS << " \"" << text << "\"\n";
  }

  void remove(CharSourceRange range) override {
    assert(Ctx);
    OS << "Remove: ";
    printSourceRange(range, *Ctx, OS);
    OS << '\n';
  }
};

} // anonymous namespace

static bool checkForMigration(StringRef resourcesPath,
                              ArrayRef<const char *> Args) {
  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
  DiagnosticConsumer *DiagClient =
    new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
  IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
  IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
      new DiagnosticsEngine(DiagID, &*DiagOpts, DiagClient));
  // Chain in -verify checker, if requested.
  VerifyDiagnosticConsumer *verifyDiag = nullptr;
  if (VerifyDiags) {
    verifyDiag = new VerifyDiagnosticConsumer(*Diags);
    Diags->setClient(verifyDiag);
  }

  CompilerInvocation CI;
  if (!CompilerInvocation::CreateFromArgs(CI, Args, *Diags))
    return true;

  if (CI.getFrontendOpts().Inputs.empty()) {
    llvm::errs() << "error: no input files\n";
    return true;
  }

  if (!CI.getLangOpts()->ObjC)
    return false;

  arcmt::checkForManualIssues(CI, CI.getFrontendOpts().Inputs[0],
                              std::make_shared<PCHContainerOperations>(),
                              Diags->getClient());
  return Diags->getClient()->getNumErrors() > 0;
}

static void printResult(FileRemapper &remapper, raw_ostream &OS) {
  remapper.forEachMapping([](StringRef, StringRef) {},
                          [&](StringRef, const llvm::MemoryBufferRef &Buffer) {
                            OS << Buffer.getBuffer();
                          });
}

static bool performTransformations(StringRef resourcesPath,
                                   ArrayRef<const char *> Args) {
  // Check first.
  if (checkForMigration(resourcesPath, Args))
    return true;

  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
  DiagnosticConsumer *DiagClient =
    new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
  IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
  IntrusiveRefCntPtr<DiagnosticsEngine> TopDiags(
      new DiagnosticsEngine(DiagID, &*DiagOpts, &*DiagClient));

  CompilerInvocation origCI;
  if (!CompilerInvocation::CreateFromArgs(origCI, Args, *TopDiags))
    return true;

  if (origCI.getFrontendOpts().Inputs.empty()) {
    llvm::errs() << "error: no input files\n";
    return true;
  }

  if (!origCI.getLangOpts()->ObjC)
    return false;

  MigrationProcess migration(origCI, std::make_shared<PCHContainerOperations>(),
                             DiagClient);

  std::vector<TransformFn>
    transforms = arcmt::getAllTransformations(origCI.getLangOpts()->getGC(),
                                 origCI.getMigratorOpts().NoFinalizeRemoval);
  assert(!transforms.empty());

  std::unique_ptr<PrintTransforms> transformPrinter;
  if (OutputTransformations)
    transformPrinter.reset(new PrintTransforms(llvm::outs()));

  for (unsigned i=0, e = transforms.size(); i != e; ++i) {
    bool err = migration.applyTransform(transforms[i], transformPrinter.get());
    if (err) return true;

    if (VerboseOpt) {
      if (i == e-1)
        llvm::errs() << "\n##### FINAL RESULT #####\n";
      else
        llvm::errs() << "\n##### OUTPUT AFTER "<< i+1 <<". TRANSFORMATION #####\n";
      printResult(migration.getRemapper(), llvm::errs());
      llvm::errs() << "\n##########################\n\n";
    }
  }

  if (!OutputTransformations)
    printResult(migration.getRemapper(), llvm::outs());

  // FIXME: TestResultForARC

  return false;
}

static bool filesCompareEqual(StringRef fname1, StringRef fname2) {
  using namespace llvm;

  ErrorOr<std::unique_ptr<MemoryBuffer>> file1 =
      MemoryBuffer::getFile(fname1, /*IsText=*/true);
  if (!file1)
    return false;

  ErrorOr<std::unique_ptr<MemoryBuffer>> file2 =
      MemoryBuffer::getFile(fname2, /*IsText=*/true);
  if (!file2)
    return false;

  return file1.get()->getBuffer() == file2.get()->getBuffer();
}

static bool verifyTransformedFiles(ArrayRef<std::string> resultFiles) {
  using namespace llvm;

  assert(!resultFiles.empty());

  std::map<StringRef, StringRef> resultMap;

  for (ArrayRef<std::string>::iterator
         I = resultFiles.begin(), E = resultFiles.end(); I != E; ++I) {
    StringRef fname(*I);
    if (!fname.endswith(".result")) {
      errs() << "error: filename '" << fname
                   << "' does not have '.result' extension\n";
      return true;
    }
    resultMap[sys::path::stem(fname)] = fname;
  }

  ErrorOr<std::unique_ptr<MemoryBuffer>> inputBuf = std::error_code();
  if (RemappingsFile.empty())
    inputBuf = MemoryBuffer::getSTDIN();
  else
    inputBuf = MemoryBuffer::getFile(RemappingsFile, /*IsText=*/true);
  if (!inputBuf) {
    errs() << "error: could not read remappings input\n";
    return true;
  }

  SmallVector<StringRef, 8> strs;
  inputBuf.get()->getBuffer().split(strs, "\n", /*MaxSplit=*/-1,
                                    /*KeepEmpty=*/false);

  if (strs.empty()) {
    errs() << "error: no files to verify from stdin\n";
    return true;
  }
  if (strs.size() % 2 != 0) {
    errs() << "error: files to verify are not original/result pairs\n";
    return true;
  }

  for (unsigned i = 0, e = strs.size(); i != e; i += 2) {
    StringRef inputOrigFname = strs[i];
    StringRef inputResultFname = strs[i+1];

    std::map<StringRef, StringRef>::iterator It;
    It = resultMap.find(sys::path::filename(inputOrigFname));
    if (It == resultMap.end()) {
      errs() << "error: '" << inputOrigFname << "' is not in the list of "
             << "transformed files to verify\n";
      return true;
    }

    if (!sys::fs::exists(It->second)) {
      errs() << "error: '" << It->second << "' does not exist\n";
      return true;
    }
    if (!sys::fs::exists(inputResultFname)) {
      errs() << "error: '" << inputResultFname << "' does not exist\n";
      return true;
    }

    if (!filesCompareEqual(It->second, inputResultFname)) {
      errs() << "error: '" << It->second << "' is different than "
             << "'" << inputResultFname << "'\n";
      return true;
    }

    resultMap.erase(It);
  }

  if (!resultMap.empty()) {
    for (std::map<StringRef, StringRef>::iterator
           I = resultMap.begin(), E = resultMap.end(); I != E; ++I)
      errs() << "error: '" << I->second << "' was not verified!\n";
    return true;
  }

  return false; 
}

//===----------------------------------------------------------------------===//
// Misc. functions.
//===----------------------------------------------------------------------===//

static void printSourceLocation(SourceLocation loc, ASTContext &Ctx,
                                raw_ostream &OS) {
  SourceManager &SM = Ctx.getSourceManager();
  PresumedLoc PL = SM.getPresumedLoc(loc);

  OS << llvm::sys::path::filename(PL.getFilename());
  OS << ":" << PL.getLine() << ":"
            << PL.getColumn();
}

static void printSourceRange(CharSourceRange range, ASTContext &Ctx,
                             raw_ostream &OS) {
  SourceManager &SM = Ctx.getSourceManager();
  const LangOptions &langOpts = Ctx.getLangOpts();

  PresumedLoc PL = SM.getPresumedLoc(range.getBegin());

  OS << llvm::sys::path::filename(PL.getFilename());
  OS << " [" << PL.getLine() << ":"
             << PL.getColumn();
  OS << " - ";

  SourceLocation end = range.getEnd();
  PL = SM.getPresumedLoc(end);

  unsigned endCol = PL.getColumn() - 1;
  if (!range.isTokenRange())
    endCol += Lexer::MeasureTokenLength(end, SM, langOpts);
  OS << PL.getLine() << ":" << endCol << "]";
}

//===----------------------------------------------------------------------===//
// Command line processing.
//===----------------------------------------------------------------------===//

int main(int argc, const char **argv) {
  void *MainAddr = (void*) (intptr_t) GetExecutablePath;
  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);

  std::string
    resourcesPath = CompilerInvocation::GetResourcesPath(argv[0], MainAddr);

  int optargc = 0;
  for (; optargc != argc; ++optargc) {
    if (StringRef(argv[optargc]) == "--args")
      break;
  }
  llvm::cl::ParseCommandLineOptions(optargc, argv, "arcmt-test");

  if (VerifyTransformedFiles) {
    if (ResultFiles.empty()) {
      llvm::cl::PrintHelpMessage();
      return 1;
    }
    return verifyTransformedFiles(ResultFiles);
  }

  if (optargc == argc) {
    llvm::cl::PrintHelpMessage();
    return 1;
  }

  ArrayRef<const char*> Args(argv+optargc+1, argc-optargc-1);

  if (CheckOnly)
    return checkForMigration(resourcesPath, Args);

  return performTransformations(resourcesPath, Args);
}
