// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/platform_file.h"

#include "base/file_path.h"
#include "base/logging.h"
#include "base/threading/thread_restrictions.h"

namespace base {

PlatformFile CreatePlatformFile(const FilePath& name,
                                int flags,
                                bool* created,
                                PlatformFileError* error_code) {
  base::ThreadRestrictions::AssertIOAllowed();

  DWORD disposition = 0;

  if (flags & PLATFORM_FILE_OPEN)
    disposition = OPEN_EXISTING;

  if (flags & PLATFORM_FILE_CREATE) {
    DCHECK(!disposition);
    disposition = CREATE_NEW;
  }

  if (flags & PLATFORM_FILE_OPEN_ALWAYS) {
    DCHECK(!disposition);
    disposition = OPEN_ALWAYS;
  }

  if (flags & PLATFORM_FILE_CREATE_ALWAYS) {
    DCHECK(!disposition);
    disposition = CREATE_ALWAYS;
  }

  if (flags & PLATFORM_FILE_TRUNCATE) {
    DCHECK(!disposition);
    DCHECK(flags & PLATFORM_FILE_WRITE);
    disposition = TRUNCATE_EXISTING;
  }

  if (!disposition) {
    NOTREACHED();
    return NULL;
  }

  DWORD access = (flags & PLATFORM_FILE_READ) ? GENERIC_READ : 0;
  if (flags & PLATFORM_FILE_WRITE)
    access |= GENERIC_WRITE;
  if (flags & PLATFORM_FILE_WRITE_ATTRIBUTES)
    access |= FILE_WRITE_ATTRIBUTES;

  DWORD sharing = (flags & PLATFORM_FILE_EXCLUSIVE_READ) ? 0 : FILE_SHARE_READ;
  if (!(flags & PLATFORM_FILE_EXCLUSIVE_WRITE))
    sharing |= FILE_SHARE_WRITE;

  DWORD create_flags = 0;
  if (flags & PLATFORM_FILE_ASYNC)
    create_flags |= FILE_FLAG_OVERLAPPED;
  if (flags & PLATFORM_FILE_TEMPORARY)
    create_flags |= FILE_ATTRIBUTE_TEMPORARY;
  if (flags & PLATFORM_FILE_HIDDEN)
    create_flags |= FILE_ATTRIBUTE_HIDDEN;
  if (flags & PLATFORM_FILE_DELETE_ON_CLOSE)
    create_flags |= FILE_FLAG_DELETE_ON_CLOSE;

  HANDLE file = CreateFile(name.value().c_str(), access, sharing, NULL,
                           disposition, create_flags, NULL);

  if (created && (INVALID_HANDLE_VALUE != file)) {
    if (flags & (PLATFORM_FILE_OPEN_ALWAYS))
      *created = (ERROR_ALREADY_EXISTS != GetLastError());
    else if (flags & (PLATFORM_FILE_CREATE_ALWAYS | PLATFORM_FILE_CREATE))
      *created = true;
  }

  if (error_code) {
    if (file != kInvalidPlatformFileValue)
      *error_code = PLATFORM_FILE_OK;
    else {
      DWORD last_error = GetLastError();
      switch (last_error) {
        case ERROR_SHARING_VIOLATION:
          *error_code = PLATFORM_FILE_ERROR_IN_USE;
          break;
        case ERROR_FILE_EXISTS:
          *error_code = PLATFORM_FILE_ERROR_EXISTS;
          break;
        case ERROR_FILE_NOT_FOUND:
          *error_code = PLATFORM_FILE_ERROR_NOT_FOUND;
          break;
        case ERROR_ACCESS_DENIED:
          *error_code = PLATFORM_FILE_ERROR_ACCESS_DENIED;
          break;
        default:
          *error_code = PLATFORM_FILE_ERROR_FAILED;
      }
    }
  }

  return file;
}

bool ClosePlatformFile(PlatformFile file) {
  base::ThreadRestrictions::AssertIOAllowed();
  return (CloseHandle(file) != 0);
}

int ReadPlatformFile(PlatformFile file, int64 offset, char* data, int size) {
  base::ThreadRestrictions::AssertIOAllowed();
  if (file == kInvalidPlatformFileValue)
    return -1;

  LARGE_INTEGER offset_li;
  offset_li.QuadPart = offset;

  OVERLAPPED overlapped = {0};
  overlapped.Offset = offset_li.LowPart;
  overlapped.OffsetHigh = offset_li.HighPart;

  DWORD bytes_read;
  if (::ReadFile(file, data, size, &bytes_read, &overlapped) != 0)
    return bytes_read;
  else if (ERROR_HANDLE_EOF == GetLastError())
    return 0;

  return -1;
}

int WritePlatformFile(PlatformFile file, int64 offset,
                      const char* data, int size) {
  base::ThreadRestrictions::AssertIOAllowed();
  if (file == kInvalidPlatformFileValue)
    return -1;

  LARGE_INTEGER offset_li;
  offset_li.QuadPart = offset;

  OVERLAPPED overlapped = {0};
  overlapped.Offset = offset_li.LowPart;
  overlapped.OffsetHigh = offset_li.HighPart;

  DWORD bytes_written;
  if (::WriteFile(file, data, size, &bytes_written, &overlapped) != 0)
    return bytes_written;

  return -1;
}

bool TruncatePlatformFile(PlatformFile file, int64 length) {
  base::ThreadRestrictions::AssertIOAllowed();
  if (file == kInvalidPlatformFileValue)
    return false;

  // Get the current file pointer.
  LARGE_INTEGER file_pointer;
  LARGE_INTEGER zero;
  zero.QuadPart = 0;
  if (::SetFilePointerEx(file, zero, &file_pointer, FILE_CURRENT) == 0)
    return false;

  LARGE_INTEGER length_li;
  length_li.QuadPart = length;
  // If length > file size, SetFilePointerEx() should extend the file
  // with zeroes on all Windows standard file systems (NTFS, FATxx).
  if (!::SetFilePointerEx(file, length_li, NULL, FILE_BEGIN))
    return false;

  // Set the new file length and move the file pointer to its old position.
  // This is consistent with ftruncate()'s behavior, even when the file
  // pointer points to a location beyond the end of the file.
  return ((::SetEndOfFile(file) != 0) &&
          (::SetFilePointerEx(file, file_pointer, NULL, FILE_BEGIN) != 0));
}

bool FlushPlatformFile(PlatformFile file) {
  base::ThreadRestrictions::AssertIOAllowed();
  return ((file != kInvalidPlatformFileValue) && ::FlushFileBuffers(file));
}

bool TouchPlatformFile(PlatformFile file, const base::Time& last_access_time,
                       const base::Time& last_modified_time) {
  base::ThreadRestrictions::AssertIOAllowed();
  if (file == kInvalidPlatformFileValue)
    return false;

  FILETIME last_access_filetime = last_access_time.ToFileTime();
  FILETIME last_modified_filetime = last_modified_time.ToFileTime();
  return (::SetFileTime(file, NULL, &last_access_filetime,
                        &last_modified_filetime) != 0);
}

bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info) {
  base::ThreadRestrictions::AssertIOAllowed();
  if (!info)
    return false;

  BY_HANDLE_FILE_INFORMATION file_info;
  if (GetFileInformationByHandle(file, &file_info) == 0)
    return false;

  LARGE_INTEGER size;
  size.HighPart = file_info.nFileSizeHigh;
  size.LowPart = file_info.nFileSizeLow;
  info->size = size.QuadPart;
  info->is_directory =
      file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY != 0;
  info->is_symbolic_link = false; // Windows doesn't have symbolic links.
  info->last_modified = base::Time::FromFileTime(file_info.ftLastWriteTime);
  info->last_accessed = base::Time::FromFileTime(file_info.ftLastAccessTime);
  info->creation_time = base::Time::FromFileTime(file_info.ftCreationTime);
  return true;
}

}  // namespace disk_cache
