//===--- 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::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);
}
