//===-- ExpectedTypeTest.cpp  -----------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "ExpectedTypes.h"
#include "ParsedAST.h"
#include "TestTU.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/StringRef.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace clang {
namespace clangd {
namespace {

using ::testing::Field;
using ::testing::Matcher;
using ::testing::SizeIs;
using ::testing::UnorderedElementsAreArray;

class ExpectedTypeConversionTest : public ::testing::Test {
protected:
  void build(llvm::StringRef Code) {
    assert(!AST && "AST built twice");
    AST = TestTU::withCode(Code).build();
  }

  const NamedDecl *decl(llvm::StringRef Name) { return &findDecl(*AST, Name); }

  QualType typeOf(llvm::StringRef Name) {
    return cast<ValueDecl>(decl(Name))->getType().getCanonicalType();
  }

  /// An overload for convenience.
  llvm::Optional<OpaqueType> fromCompletionResult(const NamedDecl *D) {
    return OpaqueType::fromCompletionResult(
        ASTCtx(), CodeCompletionResult(D, CCP_Declaration));
  }

  /// A set of DeclNames whose type match each other computed by
  /// OpaqueType::fromCompletionResult.
  using EquivClass = std::set<std::string>;

  Matcher<std::map<std::string, EquivClass>>
  ClassesAre(llvm::ArrayRef<EquivClass> Classes) {
    using MapEntry = std::map<std::string, EquivClass>::value_type;

    std::vector<Matcher<MapEntry>> Elements;
    Elements.reserve(Classes.size());
    for (auto &Cls : Classes)
      Elements.push_back(Field(&MapEntry::second, Cls));
    return UnorderedElementsAreArray(Elements);
  }

  // Groups \p Decls into equivalence classes based on the result of
  // 'OpaqueType::fromCompletionResult'.
  std::map<std::string, EquivClass>
  buildEquivClasses(llvm::ArrayRef<llvm::StringRef> DeclNames) {
    std::map<std::string, EquivClass> Classes;
    for (llvm::StringRef Name : DeclNames) {
      auto Type = OpaqueType::fromType(ASTCtx(), typeOf(Name));
      Classes[std::string(Type->raw())].insert(std::string(Name));
    }
    return Classes;
  }

  ASTContext &ASTCtx() { return AST->getASTContext(); }

private:
  // Set after calling build().
  llvm::Optional<ParsedAST> AST;
};

TEST_F(ExpectedTypeConversionTest, BasicTypes) {
  build(R"cpp(
    // ints.
    bool b;
    int i;
    unsigned int ui;
    long long ll;

    // floats.
    float f;
    double d;

    // pointers
    int* iptr;
    bool* bptr;

    // user-defined types.
    struct X {};
    X user_type;
  )cpp");

  EXPECT_THAT(buildEquivClasses({"b", "i", "ui", "ll", "f", "d", "iptr", "bptr",
                                 "user_type"}),
              ClassesAre({{"b"},
                          {"i", "ui", "ll"},
                          {"f", "d"},
                          {"iptr"},
                          {"bptr"},
                          {"user_type"}}));
}

TEST_F(ExpectedTypeConversionTest, ReferencesDontMatter) {
  build(R"cpp(
    int noref;
    int & ref = noref;
    const int & const_ref = noref;
    int && rv_ref = 10;
  )cpp");

  EXPECT_THAT(buildEquivClasses({"noref", "ref", "const_ref", "rv_ref"}),
              SizeIs(1));
}

TEST_F(ExpectedTypeConversionTest, ArraysDecay) {
  build(R"cpp(
     int arr[2];
     int (&arr_ref)[2] = arr;
     int *ptr;
  )cpp");

  EXPECT_THAT(buildEquivClasses({"arr", "arr_ref", "ptr"}), SizeIs(1));
}

TEST_F(ExpectedTypeConversionTest, FunctionReturns) {
  build(R"cpp(
     int returns_int();
     int* returns_ptr();

     int int_;
     int* int_ptr;
  )cpp");

  OpaqueType IntTy = *OpaqueType::fromType(ASTCtx(), typeOf("int_"));
  EXPECT_EQ(fromCompletionResult(decl("returns_int")), IntTy);

  OpaqueType IntPtrTy = *OpaqueType::fromType(ASTCtx(), typeOf("int_ptr"));
  EXPECT_EQ(fromCompletionResult(decl("returns_ptr")), IntPtrTy);
}

TEST_F(ExpectedTypeConversionTest, Templates) {
  build(R"cpp(
template <class T>
int* returns_not_dependent();
template <class T>
T* returns_dependent();

template <class T>
int* var_not_dependent = nullptr;
template <class T>
T* var_dependent = nullptr;

int* int_ptr_;
  )cpp");

  auto IntPtrTy = *OpaqueType::fromType(ASTCtx(), typeOf("int_ptr_"));
  EXPECT_EQ(fromCompletionResult(decl("returns_not_dependent")), IntPtrTy);
  EXPECT_EQ(fromCompletionResult(decl("returns_dependent")), llvm::None);

  EXPECT_EQ(fromCompletionResult(decl("var_not_dependent")), IntPtrTy);
  EXPECT_EQ(fromCompletionResult(decl("var_dependent")), llvm::None);
}

} // namespace
} // namespace clangd
} // namespace clang
