//===-- ClangChangeNamespace.cpp - Standalone change namespace ------------===//
//
// 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 tool can be used to change the surrounding namespaces of class/function
// definitions.
//
// Example: test.cc
//    namespace na {
//    class X {};
//    namespace nb {
//    class Y { X x; };
//    } // namespace nb
//    } // namespace na
// To move the definition of class Y from namespace "na::nb" to "x::y", run:
//    clang-change-namespace --old_namespace "na::nb" \
//      --new_namespace "x::y" --file_pattern "test.cc" test.cc --
// Output:
//    namespace na {
//    class X {};
//    } // namespace na
//    namespace x {
//    namespace y {
//    class Y { na::X x; };
//    } // namespace y
//    } // namespace x

#include "ChangeNamespace.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Refactoring.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/YAMLTraits.h"

using namespace clang;
using namespace llvm;

namespace {

cl::OptionCategory ChangeNamespaceCategory("Change namespace.");

cl::opt<std::string> OldNamespace("old_namespace", cl::Required,
                                  cl::desc("Old namespace."),
                                  cl::cat(ChangeNamespaceCategory));

cl::opt<std::string> NewNamespace("new_namespace", cl::Required,
                                  cl::desc("New namespace."),
                                  cl::cat(ChangeNamespaceCategory));

cl::opt<std::string> FilePattern(
    "file_pattern", cl::Required,
    cl::desc("Only rename namespaces in files that match the given pattern."),
    cl::cat(ChangeNamespaceCategory));

cl::opt<bool> Inplace("i", cl::desc("Inplace edit <file>s, if specified."),
                      cl::cat(ChangeNamespaceCategory));

cl::opt<bool>
    DumpYAML("dump_result",
         cl::desc("Dump new file contents in YAML, if specified."),
         cl::cat(ChangeNamespaceCategory));

cl::opt<std::string> Style("style",
                           cl::desc("The style name used for reformatting."),
                           cl::init("LLVM"), cl::cat(ChangeNamespaceCategory));

cl::opt<std::string> WhiteListFile(
    "whitelist_file",
    cl::desc("A file containing regexes of symbol names that are not expected "
             "to be updated when changing namespaces around them."),
    cl::init(""), cl::cat(ChangeNamespaceCategory));

llvm::ErrorOr<std::vector<std::string>> GetWhiteListedSymbolPatterns() {
  std::vector<std::string> Patterns;
  if (WhiteListFile.empty())
    return Patterns;

  llvm::SmallVector<StringRef, 8> Lines;
  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
      llvm::MemoryBuffer::getFile(WhiteListFile);
  if (!File)
    return File.getError();
  llvm::StringRef Content = File.get()->getBuffer();
  Content.split(Lines, '\n', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
  for (auto Line : Lines)
    Patterns.push_back(Line.trim());
  return Patterns;
}

} // anonymous namespace

int main(int argc, const char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
  tooling::CommonOptionsParser OptionsParser(argc, argv,
                                             ChangeNamespaceCategory);
  const auto &Files = OptionsParser.getSourcePathList();
  tooling::RefactoringTool Tool(OptionsParser.getCompilations(), Files);
  llvm::ErrorOr<std::vector<std::string>> WhiteListPatterns =
      GetWhiteListedSymbolPatterns();
  if (!WhiteListPatterns) {
    llvm::errs() << "Failed to open whitelist file " << WhiteListFile << ". "
                 << WhiteListPatterns.getError().message() << "\n";
    return 1;
  }
  change_namespace::ChangeNamespaceTool NamespaceTool(
      OldNamespace, NewNamespace, FilePattern, *WhiteListPatterns,
      &Tool.getReplacements(), Style);
  ast_matchers::MatchFinder Finder;
  NamespaceTool.registerMatchers(&Finder);
  std::unique_ptr<tooling::FrontendActionFactory> Factory =
      tooling::newFrontendActionFactory(&Finder);

  if (int Result = Tool.run(Factory.get()))
    return Result;
  LangOptions DefaultLangOptions;
  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
  clang::TextDiagnosticPrinter DiagnosticPrinter(errs(), &*DiagOpts);
  DiagnosticsEngine Diagnostics(
      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts,
      &DiagnosticPrinter, false);
  auto &FileMgr = Tool.getFiles();
  SourceManager Sources(Diagnostics, FileMgr);
  Rewriter Rewrite(Sources, DefaultLangOptions);

  if (!formatAndApplyAllReplacements(Tool.getReplacements(), Rewrite, Style)) {
    llvm::errs() << "Failed applying all replacements.\n";
    return 1;
  }
  if (Inplace)
    return Rewrite.overwriteChangedFiles();

  std::set<llvm::StringRef> ChangedFiles;
  for (const auto &it : Tool.getReplacements())
    ChangedFiles.insert(it.first);

  if (DumpYAML) {
    auto WriteToYAML = [&](llvm::raw_ostream &OS) {
      OS << "[\n";
      for (auto I = ChangedFiles.begin(), E = ChangedFiles.end(); I != E; ++I) {
        OS << "  {\n";
        OS << "    \"FilePath\": \"" << *I << "\",\n";
        const auto Entry = FileMgr.getFile(*I);
        auto ID = Sources.getOrCreateFileID(*Entry, SrcMgr::C_User);
        std::string Content;
        llvm::raw_string_ostream ContentStream(Content);
        Rewrite.getEditBuffer(ID).write(ContentStream);
        OS << "    \"SourceText\": \""
           << llvm::yaml::escape(ContentStream.str()) << "\"\n";
        OS << "  }";
        if (I != std::prev(E))
          OS << ",\n";
      }
      OS << "\n]\n";
    };
    WriteToYAML(llvm::outs());
    return 0;
  }

  for (const auto &File : ChangedFiles) {
    const auto Entry = FileMgr.getFile(File);

    auto ID = Sources.getOrCreateFileID(*Entry, SrcMgr::C_User);
    outs() << "============== " << File << " ==============\n";
    Rewrite.getEditBuffer(ID).write(llvm::outs());
    outs() << "\n============================================\n";
  }

  return 0;
}
