//===-- ClangApplyReplacementsMain.cpp - Main file for the tool -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file provides the main function for the
/// clang-apply-replacements tool.
///
//===----------------------------------------------------------------------===//

#include "clang-apply-replacements/Tooling/ApplyReplacements.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Version.h"
#include "clang/Format/Format.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/CommandLine.h"

using namespace llvm;
using namespace clang;
using namespace clang::replace;

static cl::opt<std::string> Directory(cl::Positional, cl::Required,
                                      cl::desc("<Search Root Directory>"));

static cl::OptionCategory ReplacementCategory("Replacement Options");
static cl::OptionCategory FormattingCategory("Formatting Options");

const cl::OptionCategory *VisibleCategories[] = {&ReplacementCategory,
                                                 &FormattingCategory};

static cl::opt<bool> RemoveTUReplacementFiles(
    "remove-change-desc-files",
    cl::desc("Remove the change description files regardless of successful\n"
             "merging/replacing."),
    cl::init(false), cl::cat(ReplacementCategory));

static cl::opt<bool> DoFormat(
    "format",
    cl::desc("Enable formatting of code changed by applying replacements.\n"
             "Use -style to choose formatting style.\n"),
    cl::cat(FormattingCategory));

// FIXME: Consider making the default behaviour for finding a style
// configuration file to start the search anew for every file being changed to
// handle situations where the style is different for different parts of a
// project.

static cl::opt<std::string> FormatStyleConfig(
    "style-config",
    cl::desc("Path to a directory containing a .clang-format file\n"
             "describing a formatting style to use for formatting\n"
             "code when -style=file.\n"),
    cl::init(""), cl::cat(FormattingCategory));

static cl::opt<std::string>
    FormatStyleOpt("style", cl::desc(format::StyleOptionHelpDescription),
                   cl::init("LLVM"), cl::cat(FormattingCategory));

namespace {
// Helper object to remove the TUReplacement and TUDiagnostic (triggered by
// "remove-change-desc-files" command line option) when exiting current scope.
class ScopedFileRemover {
public:
  ScopedFileRemover(const TUReplacementFiles &Files,
                    clang::DiagnosticsEngine &Diagnostics)
      : TURFiles(Files), Diag(Diagnostics) {}

  ~ScopedFileRemover() { deleteReplacementFiles(TURFiles, Diag); }

private:
  const TUReplacementFiles &TURFiles;
  clang::DiagnosticsEngine &Diag;
};
} // namespace

static void printVersion(raw_ostream &OS) {
  OS << "clang-apply-replacements version " CLANG_VERSION_STRING << "\n";
}

int main(int argc, char **argv) {
  cl::HideUnrelatedOptions(makeArrayRef(VisibleCategories));

  cl::SetVersionPrinter(printVersion);
  cl::ParseCommandLineOptions(argc, argv);

  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions());
  DiagnosticsEngine Diagnostics(
      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), DiagOpts.get());

  // Determine a formatting style from options.
  auto FormatStyleOrError =
      format::getStyle(FormatStyleOpt, FormatStyleConfig, "LLVM");
  if (!FormatStyleOrError) {
    llvm::errs() << llvm::toString(FormatStyleOrError.takeError()) << "\n";
    return 1;
  }
  format::FormatStyle FormatStyle = std::move(*FormatStyleOrError);

  TUReplacements TURs;
  TUReplacementFiles TUFiles;

  std::error_code ErrorCode =
      collectReplacementsFromDirectory(Directory, TURs, TUFiles, Diagnostics);

  TUDiagnostics TUDs;
  TUFiles.clear();
  ErrorCode =
      collectReplacementsFromDirectory(Directory, TUDs, TUFiles, Diagnostics);

  if (ErrorCode) {
    errs() << "Trouble iterating over directory '" << Directory
           << "': " << ErrorCode.message() << "\n";
    return 1;
  }

  // Remove the TUReplacementFiles (triggered by "remove-change-desc-files"
  // command line option) when exiting main().
  std::unique_ptr<ScopedFileRemover> Remover;
  if (RemoveTUReplacementFiles)
    Remover.reset(new ScopedFileRemover(TUFiles, Diagnostics));

  FileManager Files((FileSystemOptions()));
  SourceManager SM(Diagnostics, Files);

  FileToChangesMap Changes;
  if (!mergeAndDeduplicate(TURs, TUDs, Changes, SM))
    return 1;

  tooling::ApplyChangesSpec Spec;
  Spec.Cleanup = true;
  Spec.Style = FormatStyle;
  Spec.Format = DoFormat ? tooling::ApplyChangesSpec::kAll
                         : tooling::ApplyChangesSpec::kNone;

  for (const auto &FileChange : Changes) {
    const FileEntry *Entry = FileChange.first;
    StringRef FileName = Entry->getName();
    llvm::Expected<std::string> NewFileData =
        applyChanges(FileName, FileChange.second, Spec, Diagnostics);
    if (!NewFileData) {
      errs() << llvm::toString(NewFileData.takeError()) << "\n";
      continue;
    }

    // Write new file to disk
    std::error_code EC;
    llvm::raw_fd_ostream FileStream(FileName, EC, llvm::sys::fs::F_None);
    if (EC) {
      llvm::errs() << "Could not open " << FileName << " for writing\n";
      continue;
    }
    FileStream << *NewFileData;
  }

  return 0;
}
