/* Copyright (c) 2023, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include "file_util.h"

#include <stdlib.h>

#if defined(OPENSSL_WINDOWS)
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <windows.h>
OPENSSL_MSVC_PRAGMA(warning(pop))
#else
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#endif

#include <openssl/rand.h>

#include "test_util.h"


#if defined(OPENSSL_WINDOWS)
static void PrintLastError(const char *s) {
  DWORD error = GetLastError();
  char *buffer;
  DWORD len = FormatMessageA(
      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, 0, error, 0,
      reinterpret_cast<char *>(&buffer), 0, nullptr);
  std::string msg = "unknown error";
  if (len > 0) {
    msg.assign(buffer, len);
    while (!msg.empty() && (msg.back() == '\r' || msg.back() == '\n')) {
      msg.resize(msg.size() - 1);
    }
  }
  LocalFree(buffer);
  fprintf(stderr, "%s: %s (0x%lx)\n", s, msg.c_str(), error);
}
#endif  // OPENSSL_WINDOWS

// GetTempDir returns the path to the temporary directory, or the empty string
// on error. On success, the result will include the directory separator.
static std::string GetTempDir() {
#if defined(OPENSSL_WINDOWS)
  char buf[MAX_PATH + 1];
  DWORD len = GetTempPathA(sizeof(buf), buf);
  return std::string(buf, len);
#else
  const char *tmpdir = getenv("TMPDIR");
  if (tmpdir != nullptr && *tmpdir != '\0') {
    std::string ret = tmpdir;
    if (ret.back() != '/') {
      ret.push_back('/');
    }
    return ret;
  }
#if defined(OPENSSL_ANDROID)
  return "/data/local/tmp/";
#else
  return "/tmp/";
#endif
#endif
}

bool SkipTempFileTests() {
#if defined(OPENSSL_ANDROID)
  // When running in an APK context, /data/local/tmp is unreadable. Android
  // versions before https://android-review.googlesource.com/c/1821337 do not
  // set TMPDIR to a suitable replacement.
  if (getenv("TMPDIR") == nullptr) {
    static bool should_skip = [] {
      TemporaryFile file;
      return !file.Init();
    }();
    if (should_skip) {
      fprintf(stderr, "Skipping tests with temporary files.\n");
      return true;
    }
  }
#endif
  return false;
}

TemporaryFile::~TemporaryFile() {
#if defined(OPENSSL_WINDOWS)
  if (!path_.empty() && !DeleteFileA(path_.c_str())) {
    PrintLastError("Could not delete file");
  }
#else
  if (!path_.empty() && unlink(path_.c_str()) != 0) {
    perror("Could not delete file");
  }
#endif
}

bool TemporaryFile::Init(bssl::Span<const uint8_t> content) {
  std::string temp_dir = GetTempDir();
  if (temp_dir.empty()) {
    return false;
  }

#if defined(OPENSSL_WINDOWS)
  char path[MAX_PATH];
  if (GetTempFileNameA(temp_dir.c_str(), "bssl",
                       /*uUnique=*/0, path) == 0) {
    PrintLastError("Could not create temporary");
    return false;
  }
  path_ = path;
#else
  std::string path = temp_dir + "bssl_tmp_file.XXXXXX";
  // TODO(davidben): Use |path.data()| when we require C++17.
  int fd = mkstemp(&path[0]);
  if (fd < 0) {
    perror("Could not create temporary file");
    return false;
  }
  close(fd);
  path_ = std::move(path);
#endif

  ScopedFILE file = Open("wb");
  if (file == nullptr) {
    perror("Could not open temporary file");
    return false;
  }
  if (!content.empty() &&
      fwrite(content.data(), content.size(), /*nitems=*/1, file.get()) != 1) {
    perror("Could not write temporary file");
    return false;
  }
  return true;
}

ScopedFILE TemporaryFile::Open(const char *mode) const {
  if (path_.empty()) {
    return nullptr;
  }
  return ScopedFILE(fopen(path_.c_str(), mode));
}

ScopedFD TemporaryFile::OpenFD(int flags) const {
  if (path_.empty()) {
    return ScopedFD();
  }
#if defined(OPENSSL_WINDOWS)
  return ScopedFD(_open(path_.c_str(), flags));
#else
  return ScopedFD(open(path_.c_str(), flags));
#endif
}

TemporaryDirectory::~TemporaryDirectory() {
  if (path_.empty()) {
    return;
  }

#if defined(OPENSSL_WINDOWS)
  for (const auto &file : files_) {
    if (!DeleteFileA(GetFilePath(file).c_str())) {
      PrintLastError("Could not delete file");
    }
  }
  if (!RemoveDirectoryA(path_.c_str())) {
    PrintLastError("Could not delete directory");
  }
#else
  for (const auto &file : files_) {
    if (unlink(GetFilePath(file).c_str()) != 0) {
      perror("Could not delete file");
    }
  }
  if (rmdir(path_.c_str()) != 0) {
    perror("Could not delete directory");
  }
#endif
}

bool TemporaryDirectory::Init() {
  std::string path = GetTempDir();
  if (path.empty()) {
    return false;
  }

#if defined(OPENSSL_WINDOWS)
  // For simplicity, just try the first candidate and assume the directory
  // doesn't exist. 128 bits of cryptographically secure randomness is plenty.
  uint8_t buf[16];
  RAND_bytes(buf, sizeof(buf));
  path += "bssl_tmp_dir." + EncodeHex(buf);
  if (!CreateDirectoryA(path.c_str(), /*lpSecurityAttributes=*/nullptr)) {
    perror("Could not make temporary directory");
    return false;
  }
#else
  path += "bssl_tmp_dir.XXXXXX";
  // TODO(davidben): Use |path.data()| when we require C++17.
  if (mkdtemp(&path[0]) == nullptr) {
    perror("Could not make temporary directory");
    return false;
  }
#endif

  path_ = std::move(path);
  return true;
}

bool TemporaryDirectory::AddFile(const std::string &filename,
                                 bssl::Span<const uint8_t> content) {
  if (path_.empty()) {
    return false;
  }

  ScopedFILE file(fopen(GetFilePath(filename).c_str(), "wb"));
  if (file == nullptr) {
    perror("Could not open temporary file");
    return false;
  }
  if (!content.empty() &&
      fwrite(content.data(), content.size(), /*nitems=*/1, file.get()) != 1) {
    perror("Could not write temporary file");
    return false;
  }

  files_.insert(filename);
  return true;
}
