// 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 "util/file/filesystem.h"

#include <sys/time.h>
#include <windows.h>

#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "util/misc/time.h"

namespace crashpad {

namespace {

bool IsSymbolicLink(const base::FilePath& path) {
  WIN32_FIND_DATA find_data;
  ScopedSearchHANDLE handle(FindFirstFileEx(path.value().c_str(),
                                            FindExInfoBasic,
                                            &find_data,
                                            FindExSearchNameMatch,
                                            nullptr,
                                            0));
  if (!handle.is_valid()) {
    PLOG(ERROR) << "FindFirstFileEx " << base::WideToUTF8(path.value());
    return false;
  }

  return (find_data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0 &&
         find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
}

bool LoggingRemoveDirectoryImpl(const base::FilePath& path) {
  if (!RemoveDirectory(path.value().c_str())) {
    PLOG(ERROR) << "RemoveDirectory " << base::WideToUTF8(path.value());
    return false;
  }
  return true;
}

}  // namespace

bool FileModificationTime(const base::FilePath& path, timespec* mtime) {
  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_READ,
                   FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                   nullptr,
                   OPEN_EXISTING,
                   flags,
                   nullptr));
  if (!handle.is_valid()) {
    PLOG(ERROR) << "CreateFile " << base::WideToUTF8(path.value());
    return false;
  }

  FILETIME file_mtime;
  if (!GetFileTime(handle.get(), nullptr, nullptr, &file_mtime)) {
    PLOG(ERROR) << "GetFileTime " << base::WideToUTF8(path.value());
    return false;
  }
  *mtime = FiletimeToTimespecEpoch(file_mtime);
  return true;
}

bool LoggingCreateDirectory(const base::FilePath& path,
                            FilePermissions permissions,
                            bool may_reuse) {
  if (CreateDirectory(path.value().c_str(), nullptr)) {
    return true;
  }
  if (may_reuse && GetLastError() == ERROR_ALREADY_EXISTS) {
    if (!IsDirectory(path, true)) {
      LOG(ERROR) << base::WideToUTF8(path.value()) << " not a directory";
      return false;
    }
    return true;
  }
  PLOG(ERROR) << "CreateDirectory " << base::WideToUTF8(path.value());
  return false;
}

bool MoveFileOrDirectory(const base::FilePath& source,
                         const base::FilePath& dest) {
  if (!MoveFileEx(source.value().c_str(),
                  dest.value().c_str(),
                  IsDirectory(source, false) ? 0 : MOVEFILE_REPLACE_EXISTING)) {
    PLOG(ERROR) << "MoveFileEx" << base::WideToUTF8(source.value()) << ", "
                << base::WideToUTF8(dest.value());
    return false;
  }
  return true;
}

bool IsRegularFile(const base::FilePath& path) {
  DWORD fileattr = GetFileAttributes(path.value().c_str());
  if (fileattr == INVALID_FILE_ATTRIBUTES) {
    PLOG(ERROR) << "GetFileAttributes " << base::WideToUTF8(path.value());
    return false;
  }
  if ((fileattr & FILE_ATTRIBUTE_DIRECTORY) != 0 ||
      (fileattr & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
    return false;
  }
  return true;
}

bool IsDirectory(const base::FilePath& path, bool allow_symlinks) {
  DWORD fileattr = GetFileAttributes(path.value().c_str());
  if (fileattr == INVALID_FILE_ATTRIBUTES) {
    PLOG(ERROR) << "GetFileAttributes " << base::WideToUTF8(path.value());
    return false;
  }
  if (!allow_symlinks && (fileattr & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
    return false;
  }
  return (fileattr & FILE_ATTRIBUTE_DIRECTORY) != 0;
}

bool LoggingRemoveFile(const base::FilePath& path) {
  // RemoveDirectory is used if the file is a symbolic link to a directory.
  DWORD fileattr = GetFileAttributes(path.value().c_str());
  if (fileattr != INVALID_FILE_ATTRIBUTES &&
      (fileattr & FILE_ATTRIBUTE_DIRECTORY) != 0 &&
      (fileattr & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
    return LoggingRemoveDirectoryImpl(path);
  }

  if (!DeleteFile(path.value().c_str())) {
    PLOG(ERROR) << "DeleteFile " << base::WideToUTF8(path.value());
    return false;
  }
  return true;
}

bool LoggingRemoveDirectory(const base::FilePath& path) {
  if (IsSymbolicLink(path)) {
    LOG(ERROR) << "Not a directory " << base::WideToUTF8(path.value());
    return false;
  }
  return LoggingRemoveDirectoryImpl(path);
}

}  // namespace crashpad
