//===--- swift-refactor.cpp - Test driver for local refactoring --*- C++ -*-==//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/CommandLine.h"
#include "swift/Basic/LLVMInitialize.h"
#include "swift/Frontend/Frontend.h"
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
#include "swift/IDE/Refactoring.h"
#include "swift/IDE/Utils.h"

#include <regex>

using namespace swift;
using namespace swift::ide;

namespace options {
static llvm::cl::opt<RefactoringKind>
Action(llvm::cl::desc("kind:"), llvm::cl::init(RefactoringKind::None),
       llvm::cl::values(
           clEnumValN(RefactoringKind::LocalRename,
                      "rename", "Perform rename refactoring"),
           clEnumValN(RefactoringKind::ExtractExpr,
                      "extract-expr", "Perform extract expression refactoring"),
           clEnumValN(RefactoringKind::ExtractRepeatedExpr,
                      "extract-repeat", "Perform extract repeated expression refactoring"),
           clEnumValN(RefactoringKind::FillProtocolStub,
                      "fill-stub", "Perform fill protocol stub refactoring"),
           clEnumValN(RefactoringKind::ExpandDefault,
                      "expand-default", "Perform expand default statement refactoring"),
           clEnumValN(RefactoringKind::LocalizeString,
                      "localize-string", "Perform string localization refactoring"),
           clEnumValN(RefactoringKind::CollapseNestedIfExpr,
                      "collapse-nested-if", "Perform collapse nested if statements"),
           clEnumValN(RefactoringKind::ConvertToDoCatch,
                      "convert-to-do-catch", "Perform force try to do try catch refactoring"),
           clEnumValN(RefactoringKind::SimplifyNumberLiteral,
                      "simplify-long-number", "Perform simplify long number literal refactoring"),
           clEnumValN(RefactoringKind::ConvertStringsConcatenationToInterpolation,
                      "strings-concatenation-to-interpolation", "Perform strings concatenation to interpolation refactoring"),
           clEnumValN(RefactoringKind::ExtractFunction,
                      "extract-function", "Perform extract function refactoring"),
           clEnumValN(RefactoringKind::GlobalRename,
                      "syntactic-rename", "Perform syntactic rename"),
           clEnumValN(RefactoringKind::FindGlobalRenameRanges,
                      "find-rename-ranges", "Find detailed ranges for syntactic rename"),
           clEnumValN(RefactoringKind::FindLocalRenameRanges,
                      "find-local-rename-ranges", "Find detailed ranges for local rename")));


static llvm::cl::opt<std::string>
ModuleName("module-name", llvm::cl::desc("The module name of the given test."),
            llvm::cl::init("swift_refactor"));

static llvm::cl::opt<std::string>
SourceFilename("source-filename", llvm::cl::desc("Name of the source file"));

static llvm::cl::list<std::string>
InputFilenames(llvm::cl::Positional, llvm::cl::desc("[input files...]"),
               llvm::cl::ZeroOrMore);

static llvm::cl::opt<std::string>
LineColumnPair("pos", llvm::cl::desc("Line:Column pair or /*label*/"));

static llvm::cl::opt<std::string>
EndLineColumnPair("end-pos", llvm::cl::desc("Line:Column pair or /*label*/"));

static llvm::cl::opt<std::string>
NewName("new-name", llvm::cl::desc("A given name to rename to"),
        llvm::cl::init("new_name"));

static llvm::cl::opt<std::string>
OldName("old-name", llvm::cl::desc("The expected existing name"),
        llvm::cl::init("old_name"));

static llvm::cl::opt<bool>
IsFunctionLike("is-function-like", llvm::cl::desc("The symbol being renamed is function-like"),
               llvm::cl::ValueDisallowed);

static llvm::cl::opt<bool>
IsNonProtocolType("is-non-protocol-type",
                  llvm::cl::desc("The symbol being renamed is a type and not a protocol"));

static llvm::cl::opt<bool>
DumpInJason("dump-json",
            llvm::cl::desc("Whether to dump refactoring edits in Json"),
            llvm::cl::init(false));

static llvm::cl::opt<bool>
AvailableActions("actions",
            llvm::cl::desc("Dump the available refactoring kind for a given range"),
            llvm::cl::init(false));
}

bool doesFileExist(StringRef Path) {
  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
    llvm::MemoryBuffer::getFile(Path);
  if(FileBufOrErr)
    return true;
  return false;
}

struct RefactorLoc {
  unsigned Line;
  unsigned Column;
  NameUsage Usage;
};

NameUsage convertToNameUsage(StringRef RoleString) {
  if (RoleString == "unknown")
    return NameUsage::Unknown;
  if (RoleString == "def")
    return NameUsage::Definition;
  if (RoleString == "ref")
    return NameUsage::Reference;
  if (RoleString == "call")
    return NameUsage::Call;
  llvm_unreachable("unhandled role string");
}

std::vector<RefactorLoc> getLocsByLabelOrPosition(StringRef LabelOrLineCol,
                                                         std::string &Buffer) {

  std::vector<RefactorLoc> LocResults;
  if (LabelOrLineCol.empty())
    return LocResults;

  if (LabelOrLineCol.contains(':')) {
    auto LineCol = parseLineCol(LabelOrLineCol);
    if (LineCol.hasValue()) {
      LocResults.push_back({LineCol.getValue().first,LineCol.getValue().second,
        NameUsage::Unknown});
    } else {
      llvm::errs() << "cannot parse position pair.";
    }
    return LocResults;
  }

  std::smatch Matches;
  const std::regex LabelRegex("/\\*([^ *]+)\\*/|\\n");

  std::string::const_iterator SearchStart(Buffer.cbegin());
  unsigned Line = 1;
  unsigned Column = 1;
  while (std::regex_search(SearchStart, Buffer.cend(), Matches, LabelRegex)) {
    auto EndOffset = Matches.position() + Matches.length();
    if (Matches[1].matched) {
      Column += EndOffset;
      std::string MatchedStorage(Matches[1].str());
      StringRef Matched(MatchedStorage);
      size_t ColonPos = Matched.find(':');
      if (Matched.slice(0, ColonPos) == LabelOrLineCol) {
        NameUsage Usage = NameUsage::Reference;
        if (ColonPos != StringRef::npos)
          Usage = convertToNameUsage(Matched.substr(ColonPos + 1));
        LocResults.push_back({Line, Column, Usage});
      }
    } else {
      ++Line;
      Column = 1;
    }
    SearchStart += EndOffset;
  }
  return LocResults;
}

std::vector<RenameLoc> getRenameLocs(unsigned BufferID, SourceManager &SM,
                                     ArrayRef<RefactorLoc> Locs,
                                     StringRef OldName, StringRef NewName,
                                     bool IsFunctionLike,
                                     bool IsNonProtocolType) {
  std::vector<RenameLoc> Renames;
  std::transform(Locs.begin(), Locs.end(), std::back_inserter(Renames), [&](const RefactorLoc &Loc) -> RenameLoc {
    return {Loc.Line, Loc.Column, Loc.Usage, OldName, NewName, IsFunctionLike,
      IsNonProtocolType};
  });
  return Renames;
}

RangeConfig getRange(unsigned BufferID, SourceManager &SM,
                                   RefactorLoc Start,
                                   RefactorLoc End) {
    RangeConfig Range;
    SourceLoc EndLoc = SM.getLocForLineCol(BufferID, End.Line,
                                           End.Column);
    Range.BufferId = BufferID;
    Range.Line = Start.Line;
    Range.Column = Start.Column;
    Range.Length = SM.getByteDistance(Range.getStart(SM), EndLoc);

    assert(Range.getEnd(SM) == EndLoc);
    return Range;
}

// 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).
void anchorForGetMainExecutable() {}

int main(int argc, char *argv[]) {
  INITIALIZE_LLVM(argc, argv);
  llvm::cl::ParseCommandLineOptions(argc, argv, "Swift refactor\n");
  if (options::SourceFilename.empty()) {
    llvm::errs() << "cannot find source filename\n";
    return 1;
  }
  if (!doesFileExist(options::SourceFilename)) {
    llvm::errs() << "cannot open source file.\n";
    return 1;
  }

  CompilerInvocation Invocation;
  Invocation.setMainExecutablePath(
    llvm::sys::fs::getMainExecutable(argv[0],
    reinterpret_cast<void *>(&anchorForGetMainExecutable)));
  Invocation.addInputFilename(options::SourceFilename);
  Invocation.getLangOptions().AttachCommentsToDecls = true;
  Invocation.getLangOptions().KeepTokensInSourceFile = true;

  for (auto FileName : options::InputFilenames)
    Invocation.addInputFilename(FileName);
  Invocation.setModuleName(options::ModuleName);
  CompilerInstance CI;
  // Display diagnostics to stderr.
  PrintingDiagnosticConsumer PrintDiags;
  CI.addDiagnosticConsumer(&PrintDiags);
  if (CI.setup(Invocation))
    return 1;

  switch (options::Action) {
    case RefactoringKind::GlobalRename:
    case RefactoringKind::FindGlobalRenameRanges:
      CI.performParseOnly(/*EvaluateConditionals*/true);
      break;
    default:
      CI.performSema();
  }

  SourceFile *SF = nullptr;
  for (auto Unit : CI.getMainModule()->getFiles()) {
    if (auto Current = dyn_cast<SourceFile>(Unit)) {
      if (Current->getFilename() == options::SourceFilename)
        SF = Current;
    }
    if (SF)
      break;
  }
  assert(SF && "no source file?");

  SourceManager &SM = SF->getASTContext().SourceMgr;
  unsigned BufferID = SF->getBufferID().getValue();
  std::string Buffer = SM.getRangeForBuffer(BufferID).str();

  auto Start = getLocsByLabelOrPosition(options::LineColumnPair, Buffer);
  if (Start.empty()) {
    llvm::errs() << "cannot parse position pair.";
    return 1;
  }

  RefactorLoc EndLoc = Start.front();
  if (options::EndLineColumnPair.getNumOccurrences() == 1) {
    auto End = getLocsByLabelOrPosition(options::EndLineColumnPair, Buffer);
    if (End.size() > 1) {
      llvm::errs() << "only a single start and end position may be specified.";
      return 1;
    }
    EndLoc = End.front();
  }

  RefactorLoc &StartLoc = Start.front();


  if (options::Action == RefactoringKind::FindLocalRenameRanges) {
    RangeConfig Range = getRange(BufferID, SM, StartLoc, EndLoc);
    FindRenameRangesAnnotatingConsumer Consumer(SM, BufferID, llvm::outs());
    return findLocalRenameRanges(SF, Range, Consumer, PrintDiags);
  }

  if (options::Action == RefactoringKind::GlobalRename ||
      options::Action == RefactoringKind::FindGlobalRenameRanges) {
    if (!options::OldName.getNumOccurrences()) {
      llvm::errs() << "old-name must be specified.";
      return 1;
    }
    if (options::Action == RefactoringKind::GlobalRename && !options::NewName.getNumOccurrences()) {
      llvm::errs() << "new-name must be specified.";
      return 1;
    }

    std::string NewName = options::NewName;
    if (!options::NewName.getNumOccurrences()) {
      // Unlike other operations, we don't want to provide a default new_name,
      // since we don't want to validate the new name.
      NewName = "";
    }

    std::vector<RenameLoc>
    RenameLocs = getRenameLocs(BufferID, SM, Start, options::OldName, NewName,
                               options::IsFunctionLike.getNumOccurrences(),
                               options::IsNonProtocolType.getNumOccurrences());

    switch (options::Action) {
    case RefactoringKind::GlobalRename: {
      SourceEditOutputConsumer EditConsumer(SM, BufferID, llvm::outs());
      return syntacticRename(SF, RenameLocs, EditConsumer, PrintDiags);
    }
    case RefactoringKind::FindGlobalRenameRanges: {
      FindRenameRangesAnnotatingConsumer Consumer(SM, BufferID, llvm::outs());
      return findSyntacticRenameRanges(SF, RenameLocs, Consumer, PrintDiags);
    }
    default:
      llvm_unreachable("unexpected refactoring kind");
    }
  }

  RangeConfig Range = getRange(BufferID, SM, StartLoc, EndLoc);

  if (options::Action == RefactoringKind::None) {
    std::vector<RefactoringKind> Scratch;
    ArrayRef<RefactoringKind> AllKinds;
    bool RangeStartMayNeedRename = false;
    AllKinds = collectAvailableRefactorings(SF, Range,RangeStartMayNeedRename,
                                            Scratch, {&PrintDiags});
    llvm::outs() << "Action begins\n";
    for (auto Kind : AllKinds) {
      llvm::outs() << getDescriptiveRefactoringKindName(Kind) << "\n";
    }
    llvm::outs() << "Action ends\n";
    return 0;
  }

  RefactoringOptions RefactoringConfig(options::Action);
  RefactoringConfig.Range = Range;
  RefactoringConfig.PreferredName = options::NewName;
  std::string Error;
  std::unique_ptr<SourceEditConsumer> pConsumer;
  if (options::DumpInJason)
    pConsumer.reset(new SourceEditJsonConsumer(llvm::outs()));
  else
    pConsumer.reset(new SourceEditOutputConsumer(SF->getASTContext().SourceMgr,
                                                      BufferID,
                                                      llvm::outs()));

  return refactorSwiftModule(CI.getMainModule(), RefactoringConfig, *pConsumer,
                             PrintDiags);
}
