// Copyright 2017 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "test/filesystem.h"

#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>

#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "gtest/gtest.h"
#include "test/errors.h"
#include "test/scoped_temp_dir.h"
#include "util/file/file_io.h"
#include "util/file/filesystem.h"
#include "util/misc/time.h"

#if defined(OS_POSIX)
#include <unistd.h>

#include "base/posix/eintr_wrapper.h"
#elif defined(OS_WIN)
#include <windows.h>
#endif

namespace crashpad {
namespace test {

namespace {

#if defined(OS_WIN)

// Detects the flags necessary to create symbolic links and stores them in
// |flags| if non-nullptr, and returns true on success. If symbolic links can’t
// be created, returns false.
bool SymbolicLinkFlags(DWORD* flags) {
  static DWORD symbolic_link_flags = []() {
    ScopedTempDir temp_dir_;

    base::FilePath target_path = temp_dir_.path().Append(L"target");
    base::FilePath symlink_path = temp_dir_.path().Append(L"symlink");
    if (::CreateSymbolicLink(
            symlink_path.value().c_str(), target_path.value().c_str(), 0)) {
      return 0;
    }

    DWORD error = GetLastError();
    if (error == ERROR_PRIVILEGE_NOT_HELD) {
      if (::CreateSymbolicLink(symlink_path.value().c_str(),
                               target_path.value().c_str(),
                               SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE)) {
        return SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
      }

      // This may fail with ERROR_INVALID_PARAMETER if the OS is too old to
      // understand SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE, so keep
      // ERROR_PRIVILEGE_NOT_HELD for |error|.
    }

    // Don’t use ErrorMessage() here because the second CreateSymbolicLink() may
    // have scrambled it. Use the saved |error| value instead.
    EXPECT_EQ(error, static_cast<DWORD>(ERROR_PRIVILEGE_NOT_HELD))
        << "CreateSymbolicLink: " << logging::SystemErrorCodeToString(error);
    return -1;
  }();

  if (symbolic_link_flags == static_cast<DWORD>(-1)) {
    return false;
  }

  if (flags) {
    *flags = symbolic_link_flags;
  }

  return true;
}

#endif  // OS_WIN

}  // namespace

bool CreateFile(const base::FilePath& file) {
  ScopedFileHandle fd(LoggingOpenFileForWrite(
      file, FileWriteMode::kCreateOrFail, FilePermissions::kOwnerOnly));
  EXPECT_TRUE(fd.is_valid());
  return fd.is_valid();
}

bool PathExists(const base::FilePath& path) {
#if defined(OS_POSIX)
  struct stat st;
  if (lstat(path.value().c_str(), &st) != 0) {
    EXPECT_EQ(errno, ENOENT) << ErrnoMessage("lstat ") << path.value();
    return false;
  }
  return true;
#elif defined(OS_WIN)
  if (GetFileAttributes(path.value().c_str()) == INVALID_FILE_ATTRIBUTES) {
    EXPECT_EQ(GetLastError(), static_cast<DWORD>(ERROR_FILE_NOT_FOUND))
        << ErrorMessage("GetFileAttributes ") << base::WideToUTF8(path.value());
    return false;
  }
  return true;
#endif
}

bool SetFileModificationTime(const base::FilePath& path,
                             const timespec& mtime) {
#if defined(OS_APPLE)
  // utimensat() isn't available on macOS until 10.13, so lutimes() is used
  // instead.
  struct stat st;
  if (lstat(path.value().c_str(), &st) != 0) {
    PLOG(ERROR) << "lstat " << path.value();
    return false;
  }
  timeval times[2];
  EXPECT_TRUE(TimespecToTimeval(st.st_atimespec, &times[0]));
  EXPECT_TRUE(TimespecToTimeval(mtime, &times[1]));
  if (lutimes(path.value().c_str(), times) != 0) {
    PLOG(ERROR) << "lutimes " << path.value();
    return false;
  }
  return true;
#elif defined(OS_POSIX)
  timespec times[2];
  times[0].tv_sec = 0;
  times[0].tv_nsec = UTIME_OMIT;
  times[1] = mtime;
  if (utimensat(AT_FDCWD, path.value().c_str(), times, AT_SYMLINK_NOFOLLOW) !=
      0) {
    PLOG(ERROR) << "utimensat " << path.value();
    return false;
  }
  return true;
#elif defined(OS_WIN)
  DWORD flags = FILE_FLAG_OPEN_REPARSE_POINT;
  if (IsDirectory(path, true)) {
    // required for directory handles
    flags |= FILE_FLAG_BACKUP_SEMANTICS;
  }

  ScopedFileHandle handle(::CreateFile(path.value().c_str(),
                                       GENERIC_WRITE,
                                       FILE_SHARE_READ | FILE_SHARE_WRITE,
                                       nullptr,
                                       OPEN_EXISTING,
                                       flags,
                                       nullptr));
  if (!handle.is_valid()) {
    PLOG(ERROR) << "CreateFile " << base::WideToUTF8(path.value());
    return false;
  }

  FILETIME filetime = TimespecToFiletimeEpoch(mtime);
  if (!SetFileTime(handle.get(), nullptr, nullptr, &filetime)) {
    PLOG(ERROR) << "SetFileTime " << base::WideToUTF8(path.value());
    return false;
  }
  return true;
#endif  // OS_APPLE
}

#if !defined(OS_FUCHSIA)

bool CanCreateSymbolicLinks() {
#if defined(OS_POSIX)
  return true;
#elif defined(OS_WIN)
  return SymbolicLinkFlags(nullptr);
#endif  // OS_POSIX
}

bool CreateSymbolicLink(const base::FilePath& target_path,
                        const base::FilePath& symlink_path) {
#if defined(OS_POSIX)
  int rv = HANDLE_EINTR(
      symlink(target_path.value().c_str(), symlink_path.value().c_str()));
  if (rv != 0) {
    PLOG(ERROR) << "symlink";
    return false;
  }
  return true;
#elif defined(OS_WIN)
  DWORD symbolic_link_flags = 0;
  SymbolicLinkFlags(&symbolic_link_flags);
  if (!::CreateSymbolicLink(
          symlink_path.value().c_str(),
          target_path.value().c_str(),
          symbolic_link_flags |
              (IsDirectory(target_path, true) ? SYMBOLIC_LINK_FLAG_DIRECTORY
                                              : 0))) {
    PLOG(ERROR) << "CreateSymbolicLink";
    return false;
  }
  return true;
#endif  // OS_POSIX
}

#endif  // !OS_FUCHSIA

}  // namespace test
}  // namespace crashpad
