//===--- FileSystem.cpp - Extra helpers for manipulating files ------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/Basic/FileSystem.h"

#include "swift/Basic/LLVM.h"
#include "clang/Basic/FileManager.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/VirtualFileSystem.h"

using namespace swift;

namespace {
  class OpenFileRAII {
    static const int INVALID_FD = -1;
  public:
    int fd = INVALID_FD;

    ~OpenFileRAII() {
      if (fd != INVALID_FD)
        llvm::sys::Process::SafelyCloseFileDescriptor(fd);
    }
  };
} // end anonymous namespace

/// Does some simple checking to see if a temporary file can be written next to
/// \p outputPath and then renamed into place.
///
/// Helper for swift::atomicallyWritingToFile.
///
/// If the result is an error, the write won't succeed at all, and the calling
/// operation should bail out early.
static llvm::ErrorOr<bool>
canUseTemporaryForWrite(const StringRef outputPath) {
  namespace fs = llvm::sys::fs;

  if (outputPath == "-") {
    // Special case: "-" represents stdout, and LLVM's output stream APIs are
    // aware of this. It doesn't make sense to use a temporary in this case.
    return false;
  }

  fs::file_status status;
  (void)fs::status(outputPath, status);
  if (!fs::exists(status)) {
    // Assume we'll be able to write to both a temporary file and to the final
    // destination if the final destination doesn't exist yet.
    return true;
  }

  // Fail early if we can't write to the final destination.
  if (!fs::can_write(outputPath))
    return llvm::make_error_code(llvm::errc::operation_not_permitted);

  // Only use a temporary if the output is a regular file. This handles
  // things like '-o /dev/null'
  return fs::is_regular_file(status);
}

/// Attempts to open a temporary file next to \p outputPath, with the intent
/// that once the file has been written it will be renamed into place.
///
/// Helper for swift::atomicallyWritingToFile.
///
/// \param[out] openedStream On success, a stream opened for writing to the
/// temporary file that was just created.
/// \param outputPath The path to the final output file, which is used to decide
/// where to put the temporary.
///
/// \returns The path to the temporary file that was opened, or \c None if the
/// file couldn't be created.
static Optional<std::string>
tryToOpenTemporaryFile(Optional<llvm::raw_fd_ostream> &openedStream,
                       const StringRef outputPath) {
  namespace fs = llvm::sys::fs;

  // Create a temporary file path.
  // Insert a placeholder for a random suffix before the extension (if any).
  // Then because some tools glob for build artifacts (such as clang's own
  // GlobalModuleIndex.cpp), also append .tmp.
  SmallString<128> tempPath;
  const StringRef outputExtension = llvm::sys::path::extension(outputPath);
  tempPath = outputPath.drop_back(outputExtension.size());
  tempPath += "-%%%%%%%%";
  tempPath += outputExtension;
  tempPath += ".tmp";

  int fd;
  const unsigned perms = fs::all_read | fs::all_write;
  std::error_code EC = fs::createUniqueFile(tempPath, fd, tempPath, perms);

  if (EC) {
    // Ignore the specific error; the caller has to fall back to not using a
    // temporary anyway.
    return None;
  }

  openedStream.emplace(fd, /*shouldClose=*/true);
  // Make sure the temporary file gets removed if we crash.
  llvm::sys::RemoveFileOnSignal(tempPath);
  return tempPath.str().str();
}

std::error_code swift::atomicallyWritingToFile(
    const StringRef outputPath,
    const llvm::function_ref<void(llvm::raw_pwrite_stream &)> action) {
  namespace fs = llvm::sys::fs;

  // FIXME: This is mostly a simplified version of
  // clang::CompilerInstance::createOutputFile. It would be great to share the
  // implementation.
  assert(!outputPath.empty());

  llvm::ErrorOr<bool> canUseTemporary = canUseTemporaryForWrite(outputPath);
  if (std::error_code error = canUseTemporary.getError())
    return error;

  Optional<std::string> temporaryPath;
  {
    Optional<llvm::raw_fd_ostream> OS;
    if (canUseTemporary.get()) {
      temporaryPath = tryToOpenTemporaryFile(OS, outputPath);

      if (!temporaryPath) {
        assert(!OS.hasValue());
        // If we failed to create the temporary, fall back to writing to the
        // file directly. This handles the corner case where we cannot write to
        // the directory, but can write to the file.
      }
    }

    if (!OS.hasValue()) {
      std::error_code error;
      OS.emplace(outputPath, error, fs::F_None);
      if (error)
        return error;
    }

    action(OS.getValue());
    // In addition to scoping the use of 'OS', ending the scope here also
    // ensures that it's been flushed (by destroying it).
  }

  if (!temporaryPath.hasValue()) {
    // If we didn't use a temporary, we're done!
    return std::error_code();
  }

  return swift::moveFileIfDifferent(temporaryPath.getValue(), outputPath);
}

llvm::ErrorOr<FileDifference>
swift::areFilesDifferent(const llvm::Twine &source,
                         const llvm::Twine &destination,
                         bool allowDestinationErrors) {
  namespace fs = llvm::sys::fs;

  if (fs::equivalent(source, destination))
    return FileDifference::IdenticalFile;

  OpenFileRAII sourceFile;
  fs::file_status sourceStatus;
  if (std::error_code error = fs::openFileForRead(source, sourceFile.fd)) {
    // If we can't open the source file, fail.
    return error;
  }
  if (std::error_code error = fs::status(sourceFile.fd, sourceStatus)) {
    // If we can't stat the source file, fail.
    return error;
  }

  /// Converts an error from the destination file into either an error or
  /// DifferentContents return, depending on `allowDestinationErrors`.
  auto convertDestinationError = [=](std::error_code error) ->
      llvm::ErrorOr<FileDifference> {
    if (allowDestinationErrors)
      return FileDifference::DifferentContents;
    return error;
  };

  OpenFileRAII destFile;
  fs::file_status destStatus;
  if (std::error_code error = fs::openFileForRead(destination, destFile.fd)) {
    // If we can't open the destination file, fail in the specified fashion.
    return convertDestinationError(error);
  }
  if (std::error_code error = fs::status(destFile.fd, destStatus)) {
    // If we can't open the destination file, fail in the specified fashion.
    return convertDestinationError(error);
  }

  uint64_t size = sourceStatus.getSize();
  if (size != destStatus.getSize())
    // If the files are different sizes, they must be different.
    return FileDifference::DifferentContents;
  if (size == 0)
    // If both files are zero size, they must be the same.
    return FileDifference::SameContents;

  // The two files match in size, so we have to compare the bytes to determine
  // if they're the same.
  std::error_code sourceRegionErr;
  fs::mapped_file_region sourceRegion(sourceFile.fd,
                                      fs::mapped_file_region::readonly,
                                      size, 0, sourceRegionErr);
  if (sourceRegionErr)
    return sourceRegionErr;

  std::error_code destRegionErr;
  fs::mapped_file_region destRegion(destFile.fd,
                                    fs::mapped_file_region::readonly,
                                    size, 0, destRegionErr);

  if (destRegionErr)
    return convertDestinationError(destRegionErr);

  if (0 == memcmp(sourceRegion.const_data(), destRegion.const_data(), size))
    return FileDifference::SameContents;

  return FileDifference::DifferentContents;
}

std::error_code swift::moveFileIfDifferent(const llvm::Twine &source,
                                           const llvm::Twine &destination) {
  namespace fs = llvm::sys::fs;

  auto result = areFilesDifferent(source, destination,
                                  /*allowDestinationErrors=*/true);

  if (!result)
    return result.getError();

  switch (*result) {
  case FileDifference::IdenticalFile:
    // Do nothing for a self-move.
    return std::error_code();

  case FileDifference::SameContents:
    // Files are identical; remove the source file.
    return fs::remove(source);

  case FileDifference::DifferentContents:
    // Files are different; overwrite the destination file.
    return fs::rename(source, destination);
  }
  llvm_unreachable("Unhandled FileDifference in switch");
}

llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
swift::vfs::getFileOrSTDIN(llvm::vfs::FileSystem &FS,
                           const llvm::Twine &Filename,
                           int64_t FileSize,
                           bool RequiresNullTerminator,
                           bool IsVolatile) {
  llvm::SmallString<256> NameBuf;
  llvm::StringRef NameRef = Filename.toStringRef(NameBuf);

  if (NameRef == "-")
    return llvm::MemoryBuffer::getSTDIN();
  return FS.getBufferForFile(Filename, FileSize,
                             RequiresNullTerminator, IsVolatile);
}
