//===- unittests/Basic/FileEntryTest.cpp - Test FileEntry/FileEntryRef ----===//
//
// 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/Basic/FileEntry.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Path.h"
#include "gtest/gtest.h"

using namespace llvm;

namespace clang {

class FileEntryTestHelper {
  StringMap<llvm::ErrorOr<FileEntryRef::MapValue>> Files;
  StringMap<llvm::ErrorOr<DirectoryEntry &>> Dirs;

  SmallVector<std::unique_ptr<FileEntry>, 5> FEs;
  SmallVector<std::unique_ptr<DirectoryEntry>, 5> DEs;
  DirectoryEntryRef DR;

public:
  FileEntryTestHelper() : DR(addDirectory("dir")) {}

  DirectoryEntryRef addDirectory(StringRef Name) {
    DEs.emplace_back(new DirectoryEntry());
    return DirectoryEntryRef(*Dirs.insert({Name, *DEs.back()}).first);
  }
  DirectoryEntryRef addDirectoryAlias(StringRef Name, DirectoryEntryRef Base) {
    return DirectoryEntryRef(
        *Dirs.insert({Name, const_cast<DirectoryEntry &>(Base.getDirEntry())})
             .first);
  }

  FileEntryRef addFile(StringRef Name) {
    FEs.emplace_back(new FileEntry());
    return FileEntryRef(
        *Files.insert({Name, FileEntryRef::MapValue(*FEs.back().get(), DR)})
             .first);
  }
  FileEntryRef addFileAlias(StringRef Name, FileEntryRef Base) {
    return FileEntryRef(
        *Files
             .insert(
                 {Name, FileEntryRef::MapValue(
                            const_cast<FileEntry &>(Base.getFileEntry()), DR)})
             .first);
  }
  FileEntryRef addFileRedirect(StringRef Name, FileEntryRef Base) {
    auto Dir = addDirectory(llvm::sys::path::parent_path(Name));

    return FileEntryRef(
        *Files
             .insert({Name, FileEntryRef::MapValue(
                                const_cast<FileEntryRef::MapEntry &>(
                                    Base.getMapEntry()),
                                Dir)})
             .first);
  }
};

namespace {
TEST(FileEntryTest, FileEntryRef) {
  FileEntryTestHelper Refs;
  FileEntryRef R1 = Refs.addFile("1");
  FileEntryRef R2 = Refs.addFile("2");
  FileEntryRef R1Also = Refs.addFileAlias("1-also", R1);
  FileEntryRef R1Redirect = Refs.addFileRedirect("1-redirect", R1);
  FileEntryRef R1Redirect2 = Refs.addFileRedirect("1-redirect2", R1Redirect);

  EXPECT_EQ("1", R1.getName());
  EXPECT_EQ("2", R2.getName());
  EXPECT_EQ("1-also", R1Also.getName());
  EXPECT_EQ("1", R1Redirect.getName());
  EXPECT_EQ("1", R1Redirect2.getName());

  EXPECT_EQ("1", R1.getNameAsRequested());
  EXPECT_EQ("1-redirect", R1Redirect.getNameAsRequested());
  EXPECT_EQ("1-redirect2", R1Redirect2.getNameAsRequested());

  EXPECT_NE(&R1.getFileEntry(), &R2.getFileEntry());
  EXPECT_EQ(&R1.getFileEntry(), &R1Also.getFileEntry());
  EXPECT_EQ(&R1.getFileEntry(), &R1Redirect.getFileEntry());
  EXPECT_EQ(&R1Redirect.getFileEntry(), &R1Redirect2.getFileEntry());

  const FileEntry *CE1 = R1;
  EXPECT_EQ(CE1, &R1.getFileEntry());
}

TEST(FileEntryTest, equals) {
  FileEntryTestHelper Refs;
  FileEntryRef R1 = Refs.addFile("1");
  FileEntryRef R2 = Refs.addFile("2");
  FileEntryRef R1Also = Refs.addFileAlias("1-also", R1);
  FileEntryRef R1Redirect = Refs.addFileRedirect("1-redirect", R1);
  FileEntryRef R1Redirect2 = Refs.addFileRedirect("1-redirect2", R1Redirect);

  EXPECT_EQ(R1, &R1.getFileEntry());
  EXPECT_EQ(&R1.getFileEntry(), R1);
  EXPECT_EQ(R1, R1Also);
  EXPECT_NE(R1, &R2.getFileEntry());
  EXPECT_NE(&R2.getFileEntry(), R1);
  EXPECT_NE(R1, R2);
  EXPECT_EQ(R1, R1Redirect);
  EXPECT_EQ(R1, R1Redirect2);
}

TEST(FileEntryTest, isSameRef) {
  FileEntryTestHelper Refs;
  FileEntryRef R1 = Refs.addFile("1");
  FileEntryRef R2 = Refs.addFile("2");
  FileEntryRef R1Also = Refs.addFileAlias("1-also", R1);
  FileEntryRef R1Redirect = Refs.addFileRedirect("1-redirect", R1);
  FileEntryRef R1Redirect2 = Refs.addFileRedirect("1-redirect2", R1Redirect);

  EXPECT_TRUE(R1.isSameRef(FileEntryRef(R1)));
  EXPECT_TRUE(R1.isSameRef(FileEntryRef(R1.getMapEntry())));
  EXPECT_FALSE(R1.isSameRef(R2));
  EXPECT_FALSE(R1.isSameRef(R1Also));
  EXPECT_FALSE(R1.isSameRef(R1Redirect));
  EXPECT_FALSE(R1.isSameRef(R1Redirect2));
  EXPECT_FALSE(R1Redirect.isSameRef(R1Redirect2));
}

TEST(FileEntryTest, DenseMapInfo) {
  FileEntryTestHelper Refs;
  FileEntryRef R1 = Refs.addFile("1");
  FileEntryRef R2 = Refs.addFile("2");
  FileEntryRef R1Also = Refs.addFileAlias("1-also", R1);

  // Insert R1Also first and confirm it "wins".
  {
    SmallDenseSet<FileEntryRef, 8> Set;
    Set.insert(R1Also);
    Set.insert(R1);
    Set.insert(R2);
    EXPECT_TRUE(Set.find(R1Also)->isSameRef(R1Also));
    EXPECT_TRUE(Set.find(R1)->isSameRef(R1Also));
    EXPECT_TRUE(Set.find(R2)->isSameRef(R2));
  }

  // Insert R1Also second and confirm R1 "wins".
  {
    SmallDenseSet<FileEntryRef, 8> Set;
    Set.insert(R1);
    Set.insert(R1Also);
    Set.insert(R2);
    EXPECT_TRUE(Set.find(R1Also)->isSameRef(R1));
    EXPECT_TRUE(Set.find(R1)->isSameRef(R1));
    EXPECT_TRUE(Set.find(R2)->isSameRef(R2));
  }

  // Insert R1Also first and confirm it "wins" when looked up as FileEntry.
  {
    SmallDenseSet<FileEntryRef, 8> Set;
    Set.insert(R1Also);
    Set.insert(R1);
    Set.insert(R2);

    auto R1AlsoIt = Set.find_as(&R1Also.getFileEntry());
    ASSERT_TRUE(R1AlsoIt != Set.end());
    EXPECT_TRUE(R1AlsoIt->isSameRef(R1Also));

    auto R1It = Set.find_as(&R1.getFileEntry());
    ASSERT_TRUE(R1It != Set.end());
    EXPECT_TRUE(R1It->isSameRef(R1Also));

    auto R2It = Set.find_as(&R2.getFileEntry());
    ASSERT_TRUE(R2It != Set.end());
    EXPECT_TRUE(R2It->isSameRef(R2));
  }

  // Insert R1Also second and confirm R1 "wins" when looked up as FileEntry.
  {
    SmallDenseSet<FileEntryRef, 8> Set;
    Set.insert(R1);
    Set.insert(R1Also);
    Set.insert(R2);

    auto R1AlsoIt = Set.find_as(&R1Also.getFileEntry());
    ASSERT_TRUE(R1AlsoIt != Set.end());
    EXPECT_TRUE(R1AlsoIt->isSameRef(R1));

    auto R1It = Set.find_as(&R1.getFileEntry());
    ASSERT_TRUE(R1It != Set.end());
    EXPECT_TRUE(R1It->isSameRef(R1));

    auto R2It = Set.find_as(&R2.getFileEntry());
    ASSERT_TRUE(R2It != Set.end());
    EXPECT_TRUE(R2It->isSameRef(R2));
  }
}

TEST(DirectoryEntryTest, isSameRef) {
  FileEntryTestHelper Refs;
  DirectoryEntryRef R1 = Refs.addDirectory("1");
  DirectoryEntryRef R2 = Refs.addDirectory("2");
  DirectoryEntryRef R1Also = Refs.addDirectoryAlias("1-also", R1);

  EXPECT_TRUE(R1.isSameRef(DirectoryEntryRef(R1)));
  EXPECT_TRUE(R1.isSameRef(DirectoryEntryRef(R1.getMapEntry())));
  EXPECT_FALSE(R1.isSameRef(R2));
  EXPECT_FALSE(R1.isSameRef(R1Also));
}

TEST(DirectoryEntryTest, DenseMapInfo) {
  FileEntryTestHelper Refs;
  DirectoryEntryRef R1 = Refs.addDirectory("1");
  DirectoryEntryRef R2 = Refs.addDirectory("2");
  DirectoryEntryRef R1Also = Refs.addDirectoryAlias("1-also", R1);

  // Insert R1Also first and confirm it "wins".
  {
    SmallDenseSet<DirectoryEntryRef, 8> Set;
    Set.insert(R1Also);
    Set.insert(R1);
    Set.insert(R2);
    EXPECT_TRUE(Set.find(R1Also)->isSameRef(R1Also));
    EXPECT_TRUE(Set.find(R1)->isSameRef(R1Also));
    EXPECT_TRUE(Set.find(R2)->isSameRef(R2));
  }

  // Insert R1Also second and confirm R1 "wins".
  {
    SmallDenseSet<DirectoryEntryRef, 8> Set;
    Set.insert(R1);
    Set.insert(R1Also);
    Set.insert(R2);
    EXPECT_TRUE(Set.find(R1Also)->isSameRef(R1));
    EXPECT_TRUE(Set.find(R1)->isSameRef(R1));
    EXPECT_TRUE(Set.find(R2)->isSameRef(R2));
  }
}

} // end namespace
} // namespace clang
