#include "gtest/gtest.h"

#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"

#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "TestingSupport/TestUtilities.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/ModuleCache.h"

using namespace lldb_private;
using namespace lldb;

namespace {

class ModuleCacheTest : public testing::Test {
public:
  static void SetUpTestCase();

  static void TearDownTestCase();

protected:
  static FileSpec s_cache_dir;
  static std::string s_test_executable;

  void TryGetAndPut(const FileSpec &cache_dir, const char *hostname,
                    bool expect_download);
};
}

FileSpec ModuleCacheTest::s_cache_dir;
std::string ModuleCacheTest::s_test_executable;

static const char dummy_hostname[] = "dummy_hostname";
static const char dummy_remote_dir[] = "bin";
static const char module_name[] = "TestModule.so";
static const char module_uuid[] =
    "F4E7E991-9B61-6AD4-0073-561AC3D9FA10-C043A476";
static const uint32_t uuid_bytes = 20;
static const size_t module_size = 5602;

static FileSpec GetDummyRemotePath() {
  FileSpec fs("/", FileSpec::Style::posix);
  fs.AppendPathComponent(dummy_remote_dir);
  fs.AppendPathComponent(module_name);
  return fs;
}

static FileSpec GetUuidView(FileSpec spec) {
  spec.AppendPathComponent(".cache");
  spec.AppendPathComponent(module_uuid);
  spec.AppendPathComponent(module_name);
  return spec;
}

static FileSpec GetSysrootView(FileSpec spec, const char *hostname) {
  spec.AppendPathComponent(hostname);
  spec.AppendPathComponent(dummy_remote_dir);
  spec.AppendPathComponent(module_name);
  return spec;
}

void ModuleCacheTest::SetUpTestCase() {
  FileSystem::Initialize();
  HostInfo::Initialize();
  ObjectFileELF::Initialize();

  s_cache_dir = HostInfo::GetProcessTempDir();
  s_test_executable = GetInputFilePath(module_name);
}

void ModuleCacheTest::TearDownTestCase() {
  ObjectFileELF::Terminate();
  HostInfo::Terminate();
  FileSystem::Terminate();
}

static void VerifyDiskState(const FileSpec &cache_dir, const char *hostname) {
  FileSpec uuid_view = GetUuidView(cache_dir);
  EXPECT_TRUE(FileSystem::Instance().Exists(uuid_view))
      << "uuid_view is: " << uuid_view.GetCString();
  EXPECT_EQ(module_size, FileSystem::Instance().GetByteSize(uuid_view));

  FileSpec sysroot_view = GetSysrootView(cache_dir, hostname);
  EXPECT_TRUE(FileSystem::Instance().Exists(sysroot_view))
      << "sysroot_view is: " << sysroot_view.GetCString();
  EXPECT_EQ(module_size, FileSystem::Instance().GetByteSize(sysroot_view));
}

void ModuleCacheTest::TryGetAndPut(const FileSpec &cache_dir,
                                   const char *hostname, bool expect_download) {
  ModuleCache mc;
  ModuleSpec module_spec;
  module_spec.GetFileSpec() = GetDummyRemotePath();
  module_spec.GetUUID().SetFromStringRef(module_uuid, uuid_bytes);
  module_spec.SetObjectSize(module_size);
  ModuleSP module_sp;
  bool did_create;
  bool download_called = false;

  Status error = mc.GetAndPut(
      cache_dir, hostname, module_spec,
      [&download_called](const ModuleSpec &module_spec,
                         const FileSpec &tmp_download_file_spec) {
        download_called = true;
        EXPECT_STREQ(GetDummyRemotePath().GetCString(),
                     module_spec.GetFileSpec().GetCString());
        std::error_code ec = llvm::sys::fs::copy_file(
            s_test_executable, tmp_download_file_spec.GetCString());
        EXPECT_FALSE(ec);
        return Status();
      },
      [](const ModuleSP &module_sp, const FileSpec &tmp_download_file_spec) {
        return Status("Not supported.");
      },
      module_sp, &did_create);
  EXPECT_EQ(expect_download, download_called);

  EXPECT_TRUE(error.Success()) << "Error was: " << error.AsCString();
  EXPECT_TRUE(did_create);
  ASSERT_TRUE(bool(module_sp));

  SymbolContextList sc_list;
  EXPECT_EQ(1u, module_sp->FindFunctionSymbols(ConstString("boom"),
                                               eFunctionNameTypeFull, sc_list));
  EXPECT_STREQ(GetDummyRemotePath().GetCString(),
               module_sp->GetPlatformFileSpec().GetCString());
  EXPECT_STREQ(module_uuid, module_sp->GetUUID().GetAsString().c_str());
}

TEST_F(ModuleCacheTest, GetAndPut) {
  FileSpec test_cache_dir = s_cache_dir;
  test_cache_dir.AppendPathComponent("GetAndPut");

  const bool expect_download = true;
  TryGetAndPut(test_cache_dir, dummy_hostname, expect_download);
  VerifyDiskState(test_cache_dir, dummy_hostname);
}

TEST_F(ModuleCacheTest, GetAndPutUuidExists) {
  FileSpec test_cache_dir = s_cache_dir;
  test_cache_dir.AppendPathComponent("GetAndPutUuidExists");

  FileSpec uuid_view = GetUuidView(test_cache_dir);
  std::error_code ec =
      llvm::sys::fs::create_directories(uuid_view.GetDirectory().GetCString());
  ASSERT_FALSE(ec);
  ec = llvm::sys::fs::copy_file(s_test_executable, uuid_view.GetCString());
  ASSERT_FALSE(ec);

  const bool expect_download = false;
  TryGetAndPut(test_cache_dir, dummy_hostname, expect_download);
  VerifyDiskState(test_cache_dir, dummy_hostname);
}

TEST_F(ModuleCacheTest, GetAndPutStrangeHostname) {
  FileSpec test_cache_dir = s_cache_dir;
  test_cache_dir.AppendPathComponent("GetAndPutStrangeHostname");

  const bool expect_download = true;
  TryGetAndPut(test_cache_dir, "tab\tcolon:asterisk*", expect_download);
  VerifyDiskState(test_cache_dir, "tab_colon_asterisk_");
}
