//=== unittests/Sema/CodeCompleteTest.cpp - Code Complete tests ==============//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/ParseAST.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "clang/Tooling/Tooling.h"
#include "gtest/gtest.h"
#include "gmock/gmock.h"

namespace {

using namespace clang;
using namespace clang::tooling;
using ::testing::UnorderedElementsAre;

const char TestCCName[] = "test.cc";
using VisitedContextResults = std::vector<std::string>;

class VisitedContextFinder: public CodeCompleteConsumer {
public:
  VisitedContextFinder(VisitedContextResults &Results)
      : CodeCompleteConsumer(/*CodeCompleteOpts=*/{},
                             /*CodeCompleteConsumer*/ false),
        VCResults(Results),
        CCTUInfo(std::make_shared<GlobalCodeCompletionAllocator>()) {}

  void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
                                  CodeCompletionResult *Results,
                                  unsigned NumResults) override {
    VisitedContexts = Context.getVisitedContexts();
    VCResults = getVisitedNamespace();
  }

  CodeCompletionAllocator &getAllocator() override {
    return CCTUInfo.getAllocator();
  }

  CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }

  std::vector<std::string> getVisitedNamespace() const {
    std::vector<std::string> NSNames;
    for (const auto *Context : VisitedContexts)
      if (const auto *NS = llvm::dyn_cast<NamespaceDecl>(Context))
        NSNames.push_back(NS->getQualifiedNameAsString());
    return NSNames;
  }

private:
  VisitedContextResults& VCResults;
  CodeCompletionTUInfo CCTUInfo;
  CodeCompletionContext::VisitedContextSet VisitedContexts;
};

class CodeCompleteAction : public SyntaxOnlyAction {
public:
  CodeCompleteAction(ParsedSourceLocation P, VisitedContextResults &Results)
      : CompletePosition(std::move(P)), VCResults(Results) {}

  bool BeginInvocation(CompilerInstance &CI) override {
    CI.getFrontendOpts().CodeCompletionAt = CompletePosition;
    CI.setCodeCompletionConsumer(new VisitedContextFinder(VCResults));
    return true;
  }

private:
  // 1-based code complete position <Line, Col>;
  ParsedSourceLocation CompletePosition;
  VisitedContextResults& VCResults;
};

ParsedSourceLocation offsetToPosition(llvm::StringRef Code, size_t Offset) {
  Offset = std::min(Code.size(), Offset);
  StringRef Before = Code.substr(0, Offset);
  int Lines = Before.count('\n');
  size_t PrevNL = Before.rfind('\n');
  size_t StartOfLine = (PrevNL == StringRef::npos) ? 0 : (PrevNL + 1);
  return {TestCCName, static_cast<unsigned>(Lines + 1),
          static_cast<unsigned>(Offset - StartOfLine + 1)};
}

VisitedContextResults runCodeCompleteOnCode(StringRef Code) {
  VisitedContextResults Results;
  auto TokenOffset = Code.find('^');
  assert(TokenOffset != StringRef::npos &&
         "Completion token ^ wasn't found in Code.");
  std::string WithoutToken = Code.take_front(TokenOffset);
  WithoutToken += Code.drop_front(WithoutToken.size() + 1);
  assert(StringRef(WithoutToken).find('^') == StringRef::npos &&
         "expected exactly one completion token ^ inside the code");

  auto Action = llvm::make_unique<CodeCompleteAction>(
      offsetToPosition(WithoutToken, TokenOffset), Results);
  clang::tooling::runToolOnCodeWithArgs(Action.release(), Code, {"-std=c++11"},
                                        TestCCName);
  return Results;
}

TEST(SemaCodeCompleteTest, VisitedNSForValidQualifiedId) {
  auto VisitedNS = runCodeCompleteOnCode(R"cpp(
     namespace ns1 {}
     namespace ns2 {}
     namespace ns3 {}
     namespace ns3 { namespace nns3 {} }

     namespace foo {
     using namespace ns1;
     namespace ns4 {} // not visited
     namespace { using namespace ns2; }
     inline namespace bar { using namespace ns3::nns3; }
     } // foo
     namespace ns { foo::^ }
  )cpp");
  EXPECT_THAT(VisitedNS, UnorderedElementsAre("foo", "ns1", "ns2", "ns3::nns3",
                                              "foo::(anonymous)"));
}

TEST(SemaCodeCompleteTest, VisitedNSForInvalideQualifiedId) {
  auto VisitedNS = runCodeCompleteOnCode(R"cpp(
     namespace ns { foo::^ }
  )cpp");
  EXPECT_TRUE(VisitedNS.empty());
}

TEST(SemaCodeCompleteTest, VisitedNSWithoutQualifier) {
  auto VisitedNS = runCodeCompleteOnCode(R"cpp(
    namespace n1 {
    namespace n2 {
      void f(^) {}
    }
    }
  )cpp");
  EXPECT_THAT(VisitedNS, UnorderedElementsAre("n1", "n1::n2"));
}

} // namespace
