//===-- TestFS.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 "TestFS.h"
#include "GlobalCompilationDatabase.h"
#include "URI.h"
#include "support/Logger.h"
#include "support/Path.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Path.h"
#include <optional>

namespace clang {
namespace clangd {

namespace {

// Tries to strip \p Prefix from beginning of \p Path. Returns true on success.
// If \p Prefix doesn't match, leaves \p Path untouched and returns false.
bool pathConsumeFront(PathRef &Path, PathRef Prefix) {
  if (!pathStartsWith(Prefix, Path))
    return false;
  Path = Path.drop_front(Prefix.size());
  return true;
}
} // namespace

llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
buildTestFS(llvm::StringMap<std::string> const &Files,
            llvm::StringMap<time_t> const &Timestamps) {
  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> MemFS(
      new llvm::vfs::InMemoryFileSystem);
  MemFS->setCurrentWorkingDirectory(testRoot());
  for (auto &FileAndContents : Files) {
    llvm::StringRef File = FileAndContents.first();
    MemFS->addFile(
        File, Timestamps.lookup(File),
        llvm::MemoryBuffer::getMemBufferCopy(FileAndContents.second, File));
  }
  return MemFS;
}

MockCompilationDatabase::MockCompilationDatabase(llvm::StringRef Directory,
                                                 llvm::StringRef RelPathPrefix)
    : ExtraClangFlags({"-ffreestanding"}), Directory(Directory),
      RelPathPrefix(RelPathPrefix) {
  // -ffreestanding avoids implicit stdc-predef.h.
}

std::optional<ProjectInfo>
MockCompilationDatabase::getProjectInfo(PathRef File) const {
  return ProjectInfo{std::string(Directory)};
}

std::optional<tooling::CompileCommand>
MockCompilationDatabase::getCompileCommand(PathRef File) const {
  if (ExtraClangFlags.empty())
    return std::nullopt;

  auto FileName = llvm::sys::path::filename(File);

  // Build the compile command.
  auto CommandLine = ExtraClangFlags;
  CommandLine.insert(CommandLine.begin(), "clang");
  if (RelPathPrefix.empty()) {
    // Use the absolute path in the compile command.
    CommandLine.push_back(std::string(File));
  } else {
    // Build a relative path using RelPathPrefix.
    llvm::SmallString<32> RelativeFilePath(RelPathPrefix);
    llvm::sys::path::append(RelativeFilePath, FileName);
    CommandLine.push_back(std::string(RelativeFilePath.str()));
  }

  return {tooling::CompileCommand(Directory != llvm::StringRef()
                                      ? Directory
                                      : llvm::sys::path::parent_path(File),
                                  FileName, std::move(CommandLine), "")};
}

const char *testRoot() {
#ifdef _WIN32
  return "C:\\clangd-test";
#else
  return "/clangd-test";
#endif
}

std::string testPath(PathRef File, llvm::sys::path::Style Style) {
  assert(llvm::sys::path::is_relative(File) && "FileName should be relative");

  llvm::SmallString<32> NativeFile = File;
  llvm::sys::path::native(NativeFile, Style);
  llvm::SmallString<32> Path;
  llvm::sys::path::append(Path, Style, testRoot(), NativeFile);
  return std::string(Path.str());
}

/// unittest: is a scheme that refers to files relative to testRoot().
/// URI body is a path relative to testRoot() e.g. unittest:///x.h for
/// /clangd-test/x.h.
class TestScheme : public URIScheme {
public:
  static const char *Scheme;

  llvm::Expected<std::string>
  getAbsolutePath(llvm::StringRef /*Authority*/, llvm::StringRef Body,
                  llvm::StringRef HintPath) const override {
    if (!HintPath.empty() && !pathStartsWith(testRoot(), HintPath))
      return error("Hint path is not empty and doesn't start with {0}: {1}",
                   testRoot(), HintPath);
    if (!Body.consume_front("/"))
      return error("Body of an unittest: URI must start with '/'");
    llvm::SmallString<16> Path(Body.begin(), Body.end());
    llvm::sys::path::native(Path);
    return testPath(Path);
  }

  llvm::Expected<URI>
  uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override {
    if (!pathConsumeFront(AbsolutePath, testRoot()))
      return error("{0} does not start with {1}", AbsolutePath, testRoot());

    return URI(Scheme, /*Authority=*/"",
               llvm::sys::path::convert_to_slash(AbsolutePath));
  }
};

const char *TestScheme::Scheme = "unittest";

static URISchemeRegistry::Add<TestScheme> X(TestScheme::Scheme, "Test schema");

volatile int UnittestSchemeAnchorSource = 0;

} // namespace clangd
} // namespace clang
