//===- unittests/Serialization/VarDeclConstantInitTest.cpp - CI tests -----===//
//
// 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 "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Basic/FileManager.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/Utils.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"

#include "gtest/gtest.h"

using namespace llvm;
using namespace clang;

namespace {

class VarDeclConstantInitTest : public ::testing::Test {
  void SetUp() override {
    ASSERT_FALSE(sys::fs::createUniqueDirectory("modules-test", TestDir));
  }

  void TearDown() override { sys::fs::remove_directories(TestDir); }

public:
  SmallString<256> TestDir;

  void addFile(StringRef Path, StringRef Contents) {
    ASSERT_FALSE(sys::path::is_absolute(Path));

    SmallString<256> AbsPath(TestDir);
    sys::path::append(AbsPath, Path);

    ASSERT_FALSE(
        sys::fs::create_directories(llvm::sys::path::parent_path(AbsPath)));

    std::error_code EC;
    llvm::raw_fd_ostream OS(AbsPath, EC);
    ASSERT_FALSE(EC);
    OS << Contents;
  }
};

TEST_F(VarDeclConstantInitTest, CachedConstantInit) {
  addFile("Cached.cppm", R"cpp(
export module Fibonacci.Cache;

export namespace Fibonacci
{
	constexpr unsigned long Recursive(unsigned long n)
	{
		if (n == 0)
			return 0;
		if (n == 1)
			return 1;
		return Recursive(n - 2) + Recursive(n - 1);
	}

	template<unsigned long N>
	struct Number{};

	struct DefaultStrategy
	{
		constexpr unsigned long operator()(unsigned long n, auto... other) const
		{
			return (n + ... + other);
		}
	};

  constexpr unsigned long Compute(Number<10ul>, auto strategy)
	{
		return strategy(Recursive(10ul));
	}

	template<unsigned long N, typename Strategy = DefaultStrategy>
	constexpr unsigned long Cache = Compute(Number<N>{}, Strategy{});

  template constexpr unsigned long Cache<10ul>;
}
  )cpp");

  IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
      CompilerInstance::createDiagnostics(new DiagnosticOptions());
  CreateInvocationOptions CIOpts;
  CIOpts.Diags = Diags;
  CIOpts.VFS = llvm::vfs::createPhysicalFileSystem();

  const char *Args[] = {"clang++",       "-std=c++20",
                        "--precompile",  "-working-directory",
                        TestDir.c_str(), "Cached.cppm"};
  std::shared_ptr<CompilerInvocation> Invocation =
      createInvocation(Args, CIOpts);
  ASSERT_TRUE(Invocation);
  Invocation->getFrontendOpts().DisableFree = false;

  CompilerInstance Instance;
  Instance.setDiagnostics(Diags.get());
  Instance.setInvocation(Invocation);

  std::string CacheBMIPath = llvm::Twine(TestDir + "/Cached.pcm").str();
  Instance.getFrontendOpts().OutputFile = CacheBMIPath;

  GenerateReducedModuleInterfaceAction Action;
  ASSERT_TRUE(Instance.ExecuteAction(Action));
  ASSERT_FALSE(Diags->hasErrorOccurred());

  std::string DepArg =
      llvm::Twine("-fmodule-file=Fibonacci.Cache=" + CacheBMIPath).str();
  std::unique_ptr<ASTUnit> AST = tooling::buildASTFromCodeWithArgs(
      R"cpp(
import Fibonacci.Cache;
        )cpp",
      /*Args=*/{"-std=c++20", DepArg.c_str()});

  using namespace clang::ast_matchers;
  ASTContext &Ctx = AST->getASTContext();
  const auto *cached = selectFirst<VarDecl>(
      "Cache",
      match(varDecl(isTemplateInstantiation(), hasName("Cache")).bind("Cache"),
            Ctx));
  EXPECT_TRUE(cached);
  EXPECT_TRUE(cached->getEvaluatedStmt());
  EXPECT_TRUE(cached->getEvaluatedStmt()->WasEvaluated);
  EXPECT_TRUE(cached->getEvaluatedValue());
  EXPECT_TRUE(cached->getEvaluatedValue()->isInt());
  EXPECT_EQ(cached->getEvaluatedValue()->getInt(), 55);
}

} // anonymous namespace
