//===--- TestSupport.cpp - Clang-based refactoring tool -------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements routines that provide refactoring testing
/// utilities.
///
//===----------------------------------------------------------------------===//

#include "TestSupport.h"
#include "clang/Basic/DiagnosticError.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

namespace clang {
namespace refactor {

void TestSelectionRangesInFile::dump(raw_ostream &OS) const {
  for (const auto &Group : GroupedRanges) {
    OS << "Test selection group '" << Group.Name << "':\n";
    for (const auto &Range : Group.Ranges) {
      OS << "  " << Range.Begin << "-" << Range.End << "\n";
    }
  }
}

bool TestSelectionRangesInFile::foreachRange(
    const SourceManager &SM,
    llvm::function_ref<void(SourceRange)> Callback) const {
  const FileEntry *FE = SM.getFileManager().getFile(Filename);
  FileID FID = FE ? SM.translateFile(FE) : FileID();
  if (!FE || FID.isInvalid()) {
    llvm::errs() << "error: -selection=test:" << Filename
                 << " : given file is not in the target TU";
    return true;
  }
  SourceLocation FileLoc = SM.getLocForStartOfFile(FID);
  for (const auto &Group : GroupedRanges) {
    for (const TestSelectionRange &Range : Group.Ranges) {
      // Translate the offset pair to a true source range.
      SourceLocation Start =
          SM.getMacroArgExpandedLocation(FileLoc.getLocWithOffset(Range.Begin));
      SourceLocation End =
          SM.getMacroArgExpandedLocation(FileLoc.getLocWithOffset(Range.End));
      assert(Start.isValid() && End.isValid() && "unexpected invalid range");
      Callback(SourceRange(Start, End));
    }
  }
  return false;
}

namespace {

void dumpChanges(const tooling::AtomicChanges &Changes, raw_ostream &OS) {
  for (const auto &Change : Changes)
    OS << const_cast<tooling::AtomicChange &>(Change).toYAMLString() << "\n";
}

bool areChangesSame(const tooling::AtomicChanges &LHS,
                    const tooling::AtomicChanges &RHS) {
  if (LHS.size() != RHS.size())
    return false;
  for (const auto &I : llvm::zip(LHS, RHS)) {
    if (!(std::get<0>(I) == std::get<1>(I)))
      return false;
  }
  return true;
}

bool printRewrittenSources(const tooling::AtomicChanges &Changes,
                           raw_ostream &OS) {
  std::set<std::string> Files;
  for (const auto &Change : Changes)
    Files.insert(Change.getFilePath());
  tooling::ApplyChangesSpec Spec;
  Spec.Cleanup = false;
  for (const auto &File : Files) {
    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> BufferErr =
        llvm::MemoryBuffer::getFile(File);
    if (!BufferErr) {
      llvm::errs() << "failed to open" << File << "\n";
      return true;
    }
    auto Result = tooling::applyAtomicChanges(File, (*BufferErr)->getBuffer(),
                                              Changes, Spec);
    if (!Result) {
      llvm::errs() << toString(Result.takeError());
      return true;
    }
    OS << *Result;
  }
  return false;
}

class TestRefactoringResultConsumer final
    : public ClangRefactorToolConsumerInterface {
public:
  TestRefactoringResultConsumer(const TestSelectionRangesInFile &TestRanges)
      : TestRanges(TestRanges) {
    Results.push_back({});
  }

  ~TestRefactoringResultConsumer() {
    // Ensure all results are checked.
    for (auto &Group : Results) {
      for (auto &Result : Group) {
        if (!Result) {
          (void)llvm::toString(Result.takeError());
        }
      }
    }
  }

  void handleError(llvm::Error Err) override { handleResult(std::move(Err)); }

  void handle(tooling::AtomicChanges Changes) override {
    handleResult(std::move(Changes));
  }

  void handle(tooling::SymbolOccurrences Occurrences) override {
    tooling::RefactoringResultConsumer::handle(std::move(Occurrences));
  }

private:
  bool handleAllResults();

  void handleResult(Expected<tooling::AtomicChanges> Result) {
    Results.back().push_back(std::move(Result));
    size_t GroupIndex = Results.size() - 1;
    if (Results.back().size() >=
        TestRanges.GroupedRanges[GroupIndex].Ranges.size()) {
      ++GroupIndex;
      if (GroupIndex >= TestRanges.GroupedRanges.size()) {
        if (handleAllResults())
          exit(1); // error has occurred.
        return;
      }
      Results.push_back({});
    }
  }

  const TestSelectionRangesInFile &TestRanges;
  std::vector<std::vector<Expected<tooling::AtomicChanges>>> Results;
};

std::pair<unsigned, unsigned> getLineColumn(StringRef Filename,
                                            unsigned Offset) {
  ErrorOr<std::unique_ptr<MemoryBuffer>> ErrOrFile =
      MemoryBuffer::getFile(Filename);
  if (!ErrOrFile)
    return {0, 0};
  StringRef Source = ErrOrFile.get()->getBuffer();
  Source = Source.take_front(Offset);
  size_t LastLine = Source.find_last_of("\r\n");
  return {Source.count('\n') + 1,
          (LastLine == StringRef::npos ? Offset : Offset - LastLine) + 1};
}

} // end anonymous namespace

bool TestRefactoringResultConsumer::handleAllResults() {
  bool Failed = false;
  for (auto &Group : llvm::enumerate(Results)) {
    // All ranges in the group must produce the same result.
    Optional<tooling::AtomicChanges> CanonicalResult;
    Optional<std::string> CanonicalErrorMessage;
    for (auto &I : llvm::enumerate(Group.value())) {
      Expected<tooling::AtomicChanges> &Result = I.value();
      std::string ErrorMessage;
      bool HasResult = !!Result;
      if (!HasResult) {
        handleAllErrors(
            Result.takeError(),
            [&](StringError &Err) { ErrorMessage = Err.getMessage(); },
            [&](DiagnosticError &Err) {
              const PartialDiagnosticAt &Diag = Err.getDiagnostic();
              llvm::SmallString<100> DiagText;
              Diag.second.EmitToString(getDiags(), DiagText);
              ErrorMessage = DiagText.str().str();
            });
      }
      if (!CanonicalResult && !CanonicalErrorMessage) {
        if (HasResult)
          CanonicalResult = std::move(*Result);
        else
          CanonicalErrorMessage = std::move(ErrorMessage);
        continue;
      }

      // Verify that this result corresponds to the canonical result.
      if (CanonicalErrorMessage) {
        // The error messages must match.
        if (!HasResult && ErrorMessage == *CanonicalErrorMessage)
          continue;
      } else {
        assert(CanonicalResult && "missing canonical result");
        // The results must match.
        if (HasResult && areChangesSame(*Result, *CanonicalResult))
          continue;
      }
      Failed = true;
      // Report the mismatch.
      std::pair<unsigned, unsigned> LineColumn = getLineColumn(
          TestRanges.Filename,
          TestRanges.GroupedRanges[Group.index()].Ranges[I.index()].Begin);
      llvm::errs()
          << "error: unexpected refactoring result for range starting at "
          << LineColumn.first << ':' << LineColumn.second << " in group '"
          << TestRanges.GroupedRanges[Group.index()].Name << "':\n  ";
      if (HasResult)
        llvm::errs() << "valid result";
      else
        llvm::errs() << "error '" << ErrorMessage << "'";
      llvm::errs() << " does not match initial ";
      if (CanonicalErrorMessage)
        llvm::errs() << "error '" << *CanonicalErrorMessage << "'\n";
      else
        llvm::errs() << "valid result\n";
      if (HasResult && !CanonicalErrorMessage) {
        llvm::errs() << "  Expected to Produce:\n";
        dumpChanges(*CanonicalResult, llvm::errs());
        llvm::errs() << "  Produced:\n";
        dumpChanges(*Result, llvm::errs());
      }
    }

    // Dump the results:
    const auto &TestGroup = TestRanges.GroupedRanges[Group.index()];
    if (!CanonicalResult) {
      llvm::outs() << TestGroup.Ranges.size() << " '" << TestGroup.Name
                   << "' results:\n";
      llvm::outs() << *CanonicalErrorMessage << "\n";
    } else {
      llvm::outs() << TestGroup.Ranges.size() << " '" << TestGroup.Name
                   << "' results:\n";
      if (printRewrittenSources(*CanonicalResult, llvm::outs()))
        return true;
    }
  }
  return Failed;
}

std::unique_ptr<ClangRefactorToolConsumerInterface>
TestSelectionRangesInFile::createConsumer() const {
  return llvm::make_unique<TestRefactoringResultConsumer>(*this);
}

/// Adds the \p ColumnOffset to file offset \p Offset, without going past a
/// newline.
static unsigned addColumnOffset(StringRef Source, unsigned Offset,
                                unsigned ColumnOffset) {
  if (!ColumnOffset)
    return Offset;
  StringRef Substr = Source.drop_front(Offset).take_front(ColumnOffset);
  size_t NewlinePos = Substr.find_first_of("\r\n");
  return Offset +
         (NewlinePos == StringRef::npos ? ColumnOffset : (unsigned)NewlinePos);
}

static unsigned addEndLineOffsetAndEndColumn(StringRef Source, unsigned Offset,
                                             unsigned LineNumberOffset,
                                             unsigned Column) {
  StringRef Line = Source.drop_front(Offset);
  unsigned LineOffset = 0;
  for (; LineNumberOffset != 0; --LineNumberOffset) {
    size_t NewlinePos = Line.find_first_of("\r\n");
    // Line offset goes out of bounds.
    if (NewlinePos == StringRef::npos)
      break;
    LineOffset += NewlinePos + 1;
    Line = Line.drop_front(NewlinePos + 1);
  }
  // Source now points to the line at +lineOffset;
  size_t LineStart = Source.find_last_of("\r\n", /*From=*/Offset + LineOffset);
  return addColumnOffset(
      Source, LineStart == StringRef::npos ? 0 : LineStart + 1, Column - 1);
}

Optional<TestSelectionRangesInFile>
findTestSelectionRanges(StringRef Filename) {
  ErrorOr<std::unique_ptr<MemoryBuffer>> ErrOrFile =
      MemoryBuffer::getFile(Filename);
  if (!ErrOrFile) {
    llvm::errs() << "error: -selection=test:" << Filename
                 << " : could not open the given file";
    return None;
  }
  StringRef Source = ErrOrFile.get()->getBuffer();

  // See the doc comment for this function for the explanation of this
  // syntax.
  static Regex RangeRegex("range[[:blank:]]*([[:alpha:]_]*)?[[:blank:]]*=[[:"
                          "blank:]]*(\\+[[:digit:]]+)?[[:blank:]]*(->[[:blank:]"
                          "]*[\\+\\:[:digit:]]+)?");

  std::map<std::string, SmallVector<TestSelectionRange, 8>> GroupedRanges;

  LangOptions LangOpts;
  LangOpts.CPlusPlus = 1;
  LangOpts.CPlusPlus11 = 1;
  Lexer Lex(SourceLocation::getFromRawEncoding(0), LangOpts, Source.begin(),
            Source.begin(), Source.end());
  Lex.SetCommentRetentionState(true);
  Token Tok;
  for (Lex.LexFromRawLexer(Tok); Tok.isNot(tok::eof);
       Lex.LexFromRawLexer(Tok)) {
    if (Tok.isNot(tok::comment))
      continue;
    StringRef Comment =
        Source.substr(Tok.getLocation().getRawEncoding(), Tok.getLength());
    SmallVector<StringRef, 4> Matches;
    // Try to detect mistyped 'range:' comments to ensure tests don't miss
    // anything.
    auto DetectMistypedCommand = [&]() -> bool {
      if (Comment.contains_lower("range") && Comment.contains("=") &&
          !Comment.contains_lower("run") && !Comment.contains("CHECK")) {
        llvm::errs() << "error: suspicious comment '" << Comment
                     << "' that "
                        "resembles the range command found\n";
        llvm::errs() << "note: please reword if this isn't a range command\n";
      }
      return false;
    };
    // Allow CHECK: comments to contain range= commands.
    if (!RangeRegex.match(Comment, &Matches) || Comment.contains("CHECK")) {
      if (DetectMistypedCommand())
        return None;
      continue;
    }
    unsigned Offset = Tok.getEndLoc().getRawEncoding();
    unsigned ColumnOffset = 0;
    if (!Matches[2].empty()) {
      // Don't forget to drop the '+'!
      if (Matches[2].drop_front().getAsInteger(10, ColumnOffset))
        assert(false && "regex should have produced a number");
    }
    Offset = addColumnOffset(Source, Offset, ColumnOffset);
    unsigned EndOffset;

    if (!Matches[3].empty()) {
      static Regex EndLocRegex(
          "->[[:blank:]]*(\\+[[:digit:]]+):([[:digit:]]+)");
      SmallVector<StringRef, 4> EndLocMatches;
      if (!EndLocRegex.match(Matches[3], &EndLocMatches)) {
        if (DetectMistypedCommand())
          return None;
        continue;
      }
      unsigned EndLineOffset = 0, EndColumn = 0;
      if (EndLocMatches[1].drop_front().getAsInteger(10, EndLineOffset) ||
          EndLocMatches[2].getAsInteger(10, EndColumn))
        assert(false && "regex should have produced a number");
      EndOffset = addEndLineOffsetAndEndColumn(Source, Offset, EndLineOffset,
                                               EndColumn);
    } else {
      EndOffset = Offset;
    }
    TestSelectionRange Range = {Offset, EndOffset};
    auto It = GroupedRanges.insert(std::make_pair(
        Matches[1].str(), SmallVector<TestSelectionRange, 8>{Range}));
    if (!It.second)
      It.first->second.push_back(Range);
  }
  if (GroupedRanges.empty()) {
    llvm::errs() << "error: -selection=test:" << Filename
                 << ": no 'range' commands";
    return None;
  }

  TestSelectionRangesInFile TestRanges = {Filename.str(), {}};
  for (auto &Group : GroupedRanges)
    TestRanges.GroupedRanges.push_back({Group.first, std::move(Group.second)});
  return std::move(TestRanges);
}

} // end namespace refactor
} // end namespace clang
