//===----------------------------------------------------------------------===//
//
// 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 "llvm/CAS/UnifiedOnDiskCache.h"
#include "CASTestConfig.h"
#include "OnDiskCommonUtils.h"
#include "llvm/Testing/Support/Error.h"
#include "llvm/Testing/Support/SupportHelpers.h"
#include "gtest/gtest.h"

using namespace llvm;
using namespace llvm::cas;
using namespace llvm::cas::ondisk;
using namespace llvm::unittest::cas;

/// Visits all the files of a directory recursively and returns the sum of their
/// sizes.
static Expected<size_t> countFileSizes(StringRef Path) {
  size_t TotalSize = 0;
  std::error_code EC;
  for (sys::fs::directory_iterator DirI(Path, EC), DirE; !EC && DirI != DirE;
       DirI.increment(EC)) {
    if (DirI->type() == sys::fs::file_type::directory_file) {
      Expected<size_t> Subsize = countFileSizes(DirI->path());
      if (!Subsize)
        return Subsize.takeError();
      TotalSize += *Subsize;
      continue;
    }
    ErrorOr<sys::fs::basic_file_status> Stat = DirI->status();
    if (!Stat)
      return createFileError(DirI->path(), Stat.getError());
    TotalSize += Stat->getSize();
  }
  if (EC)
    return createFileError(Path, EC);
  return TotalSize;
}

TEST_P(CustomHasherOnDiskCASTest, UnifiedOnDiskCacheTest) {
  auto HashFn = GetParam().HashFn;
  StringRef HashName = GetParam().HashName;
  size_t HashSize = GetParam().HashSize;

  unittest::TempDir Temp("ondisk-unified", /*Unique=*/true);
  std::unique_ptr<UnifiedOnDiskCache> UniDB;

  const uint64_t SizeLimit = 1024ull * 64;
  auto reopenDB = [&]() {
    UniDB.reset();
    ASSERT_THAT_ERROR(
        UnifiedOnDiskCache::open(Temp.path(), SizeLimit, HashName, HashSize)
            .moveInto(UniDB),
        Succeeded());
  };

  reopenDB();

  HashType RootHash(HashSize);
  HashType OtherHash(HashSize);
  HashType Key1Hash(HashSize);
  HashType Key2Hash(HashSize);
  {
    OnDiskGraphDB &DB = UniDB->getGraphDB();
    std::optional<ObjectID> ID1;
    ASSERT_THAT_ERROR(store(DB, "1", {}).moveInto(ID1), Succeeded());
    std::optional<ObjectID> ID2;
    ASSERT_THAT_ERROR(store(DB, "2", {}).moveInto(ID2), Succeeded());
    std::optional<ObjectID> IDRoot;
    ASSERT_THAT_ERROR(store(DB, "root", {*ID1, *ID2}).moveInto(IDRoot),
                      Succeeded());
    ArrayRef<uint8_t> Digest = DB.getDigest(*IDRoot);
    ASSERT_EQ(Digest.size(), RootHash.size());
    llvm::copy(Digest, RootHash.data());

    std::optional<ObjectID> IDOther;
    ASSERT_THAT_ERROR(store(DB, "other", {}).moveInto(IDOther), Succeeded());
    Digest = DB.getDigest(*IDOther);
    ASSERT_EQ(Digest.size(), OtherHash.size());
    llvm::copy(Digest, OtherHash.data());

    Key1Hash = digest("key1");
    std::optional<ObjectID> Val;
    ASSERT_THAT_ERROR(
        cachePut(UniDB->getKeyValueDB(), Key1Hash, *IDRoot).moveInto(Val),
        Succeeded());
    EXPECT_EQ(IDRoot, Val);

    Key2Hash = digest("key2");
    std::optional<ObjectID> KeyID;
    ASSERT_THAT_ERROR(DB.getReference(Key2Hash).moveInto(KeyID), Succeeded());
    ASSERT_THAT_ERROR(cachePut(UniDB->getKeyValueDB(),
                               UniDB->getGraphDB().getDigest(*KeyID), *ID1)
                          .moveInto(Val),
                      Succeeded());
  }

  auto checkTree = [&](const HashType &Digest, StringRef ExpectedTree) {
    OnDiskGraphDB &DB = UniDB->getGraphDB();
    std::optional<ObjectID> ID;
    ASSERT_THAT_ERROR(DB.getReference(Digest).moveInto(ID), Succeeded());
    std::string PrintedTree;
    raw_string_ostream OS(PrintedTree);
    ASSERT_THAT_ERROR(printTree(DB, *ID, OS), Succeeded());
    EXPECT_EQ(PrintedTree, ExpectedTree);
  };
  auto checkRootTree = [&]() {
    return checkTree(RootHash, "root\n  1\n  2\n");
  };

  auto checkKey = [&](const HashType &Key, StringRef ExpectedData) {
    OnDiskGraphDB &DB = UniDB->getGraphDB();
    std::optional<ObjectID> Val;
    ASSERT_THAT_ERROR(cacheGet(UniDB->getKeyValueDB(), Key).moveInto(Val),
                      Succeeded());

    ASSERT_TRUE(Val.has_value());
    std::optional<ondisk::ObjectHandle> Obj;
    ASSERT_THAT_ERROR(DB.load(*Val).moveInto(Obj), Succeeded());
    EXPECT_EQ(toStringRef(DB.getObjectData(*Obj)), ExpectedData);
  };

  checkRootTree();
  checkTree(OtherHash, "other\n");
  checkKey(Key1Hash, "root");
  checkKey(Key2Hash, "1");

  ASSERT_THAT_ERROR(UniDB->validateActionCache(), Succeeded());
  std::optional<ValidationResult> ValidationRes;
  ASSERT_THAT_ERROR(UnifiedOnDiskCache::validateIfNeeded(
                        Temp.path(), HashName, HashSize, /*CheckHash=*/true,
                        HashFn, /*AllowRecovery=*/false,
                        /*ForceValidation=*/true,
                        /*LLVMCasBinary=*/std::nullopt)
                        .moveInto(ValidationRes),
                    Succeeded());
  ASSERT_EQ(ValidationRes, ValidationResult::Valid);

  auto storeBigObject = [&](unsigned Index) {
    SmallString<1000> Buf;
    Buf.append(970, 'a');
    raw_svector_ostream(Buf) << Index;
    std::optional<ObjectID> ID;
    ASSERT_THAT_ERROR(store(UniDB->getGraphDB(), Buf, {}).moveInto(ID),
                      Succeeded());
  };

  uint64_t PrevStoreSize = UniDB->getStorageSize();
  unsigned Index = 0;
  while (!UniDB->hasExceededSizeLimit()) {
    storeBigObject(Index++);
  }
  EXPECT_GT(UniDB->getStorageSize(), PrevStoreSize);
  UniDB->setSizeLimit(SizeLimit * 2);
  EXPECT_FALSE(UniDB->hasExceededSizeLimit());
  UniDB->setSizeLimit(SizeLimit);
  EXPECT_TRUE(UniDB->hasExceededSizeLimit());

  reopenDB();

  EXPECT_FALSE(UniDB->hasExceededSizeLimit());
  EXPECT_FALSE(UniDB->needsGarbageCollection());

  checkRootTree();
  checkKey(Key1Hash, "root");

  while (!UniDB->hasExceededSizeLimit()) {
    storeBigObject(Index++);
  }
  PrevStoreSize = UniDB->getStorageSize();
  ASSERT_THAT_ERROR(UniDB->close(), Succeeded());
  EXPECT_TRUE(UniDB->needsGarbageCollection());

  reopenDB();
  EXPECT_TRUE(UniDB->needsGarbageCollection());

  std::optional<size_t> DirSizeBefore;
  ASSERT_THAT_ERROR(countFileSizes(Temp.path()).moveInto(DirSizeBefore),
                    Succeeded());

  ASSERT_THAT_ERROR(UnifiedOnDiskCache::collectGarbage(Temp.path()),
                    Succeeded());

  std::optional<size_t> DirSizeAfter;
  ASSERT_THAT_ERROR(countFileSizes(Temp.path()).moveInto(DirSizeAfter),
                    Succeeded());
  EXPECT_LT(*DirSizeAfter, *DirSizeBefore);

  reopenDB();
  EXPECT_FALSE(UniDB->needsGarbageCollection());

  checkRootTree();
  checkKey(Key1Hash, "root");

  EXPECT_LT(UniDB->getStorageSize(), PrevStoreSize);

  // 'Other' tree and 'Key2' got garbage-collected.
  {
    OnDiskGraphDB &DB = UniDB->getGraphDB();
    std::optional<ObjectID> ID;
    ASSERT_THAT_ERROR(DB.getReference(OtherHash).moveInto(ID), Succeeded());
    EXPECT_FALSE(DB.containsObject(*ID));
    std::optional<ObjectID> Val;
    ASSERT_THAT_ERROR(cacheGet(UniDB->getKeyValueDB(), Key2Hash).moveInto(Val),
                      Succeeded());
    EXPECT_FALSE(Val.has_value());
  }
}
