//===----------------------------------------------------------------------===//
//
// 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/Serialization/ModuleCache.h"

#include "clang/Serialization/InMemoryModuleCache.h"
#include "clang/Serialization/ModuleFile.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/IOSandbox.h"
#include "llvm/Support/LockFileManager.h"
#include "llvm/Support/Path.h"

using namespace clang;

const ModuleCacheDirectory *ModuleCache::getDirectoryPtr(StringRef Path) {
  auto [ByNameIt, ByNameInserted] = ByPath.insert({Path, nullptr});
  if (!ByNameIt->second) {
    // This is a compiler-internal input/output, let's bypass the sandbox.
    auto BypassSandbox = llvm::sys::sandbox::scopedDisable();

    // If we cannot get status of the module cache directory, try if trying to
    // create it helps.
    llvm::sys::fs::file_status Status;
    if (std::error_code EC = llvm::sys::fs::status(Path, Status)) {
      // Unless the status failed because the directory does not exist yet.
      if (EC != std::errc::no_such_file_or_directory)
        return nullptr;
      // If we're unable to create the directory.
      if (llvm::sys::fs::create_directories(Path))
        return nullptr;
      // If we're unable to stat the newly created directory.
      if (llvm::sys::fs::status(Path, Status))
        return nullptr;
    }

    llvm::sys::fs::UniqueID UID = Status.getUniqueID();
    auto [ByUIDIt, ByUIDInserted] = ByUID.insert({UID, nullptr});
    if (!ByUIDIt->second)
      ByUIDIt->second = std::make_unique<ModuleCacheDirectory>();
    ByNameIt->second = ByUIDIt->second.get();
  }
  return ByNameIt->second;
}

/// Write a new timestamp file with the given path.
static void writeTimestampFile(StringRef TimestampFile) {
  std::error_code EC;
  llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::OF_None);
}

void clang::maybePruneImpl(StringRef Path, time_t PruneInterval,
                           time_t PruneAfter, bool PruneTopLevel) {
  if (PruneInterval <= 0 || PruneAfter <= 0)
    return;

  // This is a compiler-internal input/output, let's bypass the sandbox.
  auto BypassSandbox = llvm::sys::sandbox::scopedDisable();

  llvm::SmallString<128> TimestampFile(Path);
  llvm::sys::path::append(TimestampFile, "modules.timestamp");

  // Try to stat() the timestamp file.
  llvm::sys::fs::file_status StatBuf;
  if (std::error_code EC = llvm::sys::fs::status(TimestampFile, StatBuf)) {
    // If the timestamp file wasn't there, create one now.
    if (EC == std::errc::no_such_file_or_directory)
      writeTimestampFile(TimestampFile);
    return;
  }

  // Check whether the time stamp is older than our pruning interval.
  // If not, do nothing.
  time_t TimestampModTime =
      llvm::sys::toTimeT(StatBuf.getLastModificationTime());
  time_t CurrentTime = time(nullptr);
  if (CurrentTime - TimestampModTime <= PruneInterval)
    return;

  // Write a new timestamp file so that nobody else attempts to prune.
  // There is a benign race condition here, if two Clang instances happen to
  // notice at the same time that the timestamp is out-of-date.
  writeTimestampFile(TimestampFile);

  // Walk the entire module cache, looking for unused module files and module
  // indices.
  std::error_code EC;
  auto TryPruneFile = [&](StringRef FilePath) {
    // We only care about module and global module index files.
    StringRef Filename = llvm::sys::path::filename(FilePath);
    StringRef Extension = llvm::sys::path::extension(FilePath);
    if (Extension != ".pcm" && Extension != ".timestamp" &&
        Filename != "modules.idx")
      return;

    // Don't prune the pruning timestamp file.
    if (Filename == "modules.timestamp")
      return;

    // Look at this file. If we can't stat it, there's nothing interesting
    // there.
    if (llvm::sys::fs::status(FilePath, StatBuf))
      return;

    // If the file has been used recently enough, leave it there.
    time_t FileAccessTime = llvm::sys::toTimeT(StatBuf.getLastAccessedTime());
    if (CurrentTime - FileAccessTime <= PruneAfter)
      return;

    // Remove the file.
    llvm::sys::fs::remove(FilePath);

    // Remove the timestamp file created by implicit module builds.
    std::string TimestampFilename = FilePath.str() + ".timestamp";
    llvm::sys::fs::remove(TimestampFilename);
  };

  for (llvm::sys::fs::directory_iterator Dir(Path, EC), DirEnd;
       Dir != DirEnd && !EC; Dir.increment(EC)) {
    // If we don't have a directory, try to prune it as a file in the root.
    if (!llvm::sys::fs::is_directory(Dir->path())) {
      if (PruneTopLevel)
        TryPruneFile(Dir->path());
      continue;
    }

    // Walk all the files within this directory.
    for (llvm::sys::fs::directory_iterator File(Dir->path(), EC), FileEnd;
         File != FileEnd && !EC; File.increment(EC))
      TryPruneFile(File->path());

    // If we removed all the files in the directory, remove the directory
    // itself.
    if (llvm::sys::fs::directory_iterator(Dir->path(), EC) ==
            llvm::sys::fs::directory_iterator() &&
        !EC)
      llvm::sys::fs::remove(Dir->path());
  }
}

std::error_code clang::writeImpl(StringRef Path, llvm::MemoryBufferRef Buffer,
                                 off_t &Size, time_t &ModTime) {
  StringRef Extension = llvm::sys::path::extension(Path);
  SmallString<128> ModelPath = StringRef(Path).drop_back(Extension.size());
  ModelPath += "-%%%%%%%%";
  ModelPath += Extension;
  ModelPath += ".tmp";

  std::error_code EC;
  int FD;
  SmallString<128> TmpPath;
  if ((EC = llvm::sys::fs::createUniqueFile(ModelPath, FD, TmpPath))) {
    if (EC != std::errc::no_such_file_or_directory)
      return EC;

    StringRef Dir = llvm::sys::path::parent_path(Path);
    if (std::error_code InnerEC = llvm::sys::fs::create_directories(Dir))
      return InnerEC;

    if ((EC = llvm::sys::fs::createUniqueFile(ModelPath, FD, TmpPath)))
      return EC;
  }

  llvm::sys::fs::file_status Status;
  {
    llvm::raw_fd_ostream OS(FD, /*shouldClose=*/true);
    OS << Buffer.getBuffer();
    // Using the status from an open file descriptor ensures this is not racy.
    if ((EC = llvm::sys::fs::status(FD, Status)))
      return EC;
  }

  Size = Status.getSize();
  ModTime = llvm::sys::toTimeT(Status.getLastModificationTime());

  // This preserves both size and modification time.
  if ((EC = llvm::sys::fs::rename(TmpPath, Path)))
    return EC;

  return {};
}

Expected<std::unique_ptr<llvm::MemoryBuffer>>
clang::readImpl(StringRef FileName, off_t &Size, time_t &ModTime) {
  Expected<llvm::sys::fs::file_t> FD =
      llvm::sys::fs::openNativeFileForRead(FileName);
  if (!FD)
    return FD.takeError();
  llvm::scope_exit CloseFD([&FD]() { llvm::sys::fs::closeFile(*FD); });
  llvm::sys::fs::file_status Status;
  if (std::error_code EC = llvm::sys::fs::status(*FD, Status))
    return llvm::errorCodeToError(EC);
  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf =
      llvm::MemoryBuffer::getOpenFile(*FD, FileName, Status.getSize(),
                                      /*RequiresNullTerminator=*/false);
  if (!Buf)
    return llvm::errorCodeToError(Buf.getError());
  Size = Status.getSize();
  ModTime = llvm::sys::toTimeT(Status.getLastModificationTime());
  return std::move(*Buf);
}

namespace {
class CrossProcessModuleCache : public ModuleCache {
  InMemoryModuleCache InMemory;

public:
  std::unique_ptr<llvm::AdvisoryLock>
  getLock(StringRef ModuleFilename) override {
    return std::make_unique<llvm::LockFileManager>(ModuleFilename);
  }

  std::time_t getModuleTimestamp(StringRef ModuleFilename) override {
    // This is a compiler-internal input/output, let's bypass the sandbox.
    auto BypassSandbox = llvm::sys::sandbox::scopedDisable();

    std::string TimestampFilename =
        serialization::ModuleFile::getTimestampFilename(ModuleFilename);
    llvm::sys::fs::file_status Status;
    if (llvm::sys::fs::status(TimestampFilename, Status) != std::error_code{})
      return 0;
    return llvm::sys::toTimeT(Status.getLastModificationTime());
  }

  void updateModuleTimestamp(StringRef ModuleFilename) override {
    // This is a compiler-internal input/output, let's bypass the sandbox.
    auto BypassSandbox = llvm::sys::sandbox::scopedDisable();

    // Overwrite the timestamp file contents so that file's mtime changes.
    std::error_code EC;
    llvm::raw_fd_ostream OS(
        serialization::ModuleFile::getTimestampFilename(ModuleFilename), EC,
        llvm::sys::fs::OF_TextWithCRLF);
    if (EC)
      return;
    OS << "Timestamp file\n";
    OS.close();
    OS.clear_error(); // Avoid triggering a fatal error.
  }

  void maybePrune(StringRef Path, time_t PruneInterval,
                  time_t PruneAfter) override {
    // This is a compiler-internal input/output, let's bypass the sandbox.
    auto BypassSandbox = llvm::sys::sandbox::scopedDisable();

    maybePruneImpl(Path, PruneInterval, PruneAfter);
  }

  InMemoryModuleCache &getInMemoryModuleCache() override { return InMemory; }
  const InMemoryModuleCache &getInMemoryModuleCache() const override {
    return InMemory;
  }

  std::error_code write(StringRef Path, llvm::MemoryBufferRef Buffer,
                        off_t &Size, time_t &ModTime) override {
    // This is a compiler-internal input/output, let's bypass the sandbox.
    auto BypassSandbox = llvm::sys::sandbox::scopedDisable();

    return writeImpl(Path, Buffer, Size, ModTime);
  }

  Expected<std::unique_ptr<llvm::MemoryBuffer>>
  read(StringRef FileName, off_t &Size, time_t &ModTime) override {
    // This is a compiler-internal input/output, let's bypass the sandbox.
    auto BypassSandbox = llvm::sys::sandbox::scopedDisable();

    return readImpl(FileName, Size, ModTime);
  }
};
} // namespace

std::shared_ptr<ModuleCache> clang::createCrossProcessModuleCache() {
  return std::make_shared<CrossProcessModuleCache>();
}
