// Copyright (c) 2011 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 "storage/browser/database/vfs_backend.h"

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "third_party/sqlite/sqlite3.h"

namespace storage {

static const int kFileTypeMask = 0x00007F00;

// static
bool VfsBackend::OpenTypeIsReadWrite(int desired_flags) {
  return (desired_flags & SQLITE_OPEN_READWRITE) != 0;
}

// static
bool VfsBackend::OpenFileFlagsAreConsistent(int desired_flags) {
  const int file_type = desired_flags & kFileTypeMask;
  const bool is_exclusive = (desired_flags & SQLITE_OPEN_EXCLUSIVE) != 0;
  const bool is_delete = (desired_flags & SQLITE_OPEN_DELETEONCLOSE) != 0;
  const bool is_create = (desired_flags & SQLITE_OPEN_CREATE) != 0;
  const bool is_read_only = (desired_flags & SQLITE_OPEN_READONLY) != 0;
  const bool is_read_write = (desired_flags & SQLITE_OPEN_READWRITE) != 0;

  // All files should be opened either read-write or read-only, but not both.
  if (is_read_only == is_read_write)
    return false;

  // If a new file is created, it must also be writable.
  if (is_create && !is_read_write)
    return false;

  // If we're accessing an existing file, we cannot give exclusive access, and
  // we can't delete it.
  // Normally, we'd also check that 'is_delete' is false for a main DB, main
  // journal or master journal file; however, when in incognito mode, we use
  // the SQLITE_OPEN_DELETEONCLOSE flag when opening those files too and keep
  // an open handle to them for as long as the incognito profile is around.
  if ((is_exclusive || is_delete) && !is_create)
    return false;

  // Make sure we're opening the DB directory or that a file type is set.
  return (file_type == SQLITE_OPEN_MAIN_DB) ||
         (file_type == SQLITE_OPEN_TEMP_DB) ||
         (file_type == SQLITE_OPEN_MAIN_JOURNAL) ||
         (file_type == SQLITE_OPEN_TEMP_JOURNAL) ||
         (file_type == SQLITE_OPEN_SUBJOURNAL) ||
         (file_type == SQLITE_OPEN_MASTER_JOURNAL) ||
         (file_type == SQLITE_OPEN_TRANSIENT_DB);
}

// static
base::File VfsBackend::OpenFile(const base::FilePath& file_path,
                                int desired_flags) {
  DCHECK(!file_path.empty());

  // Verify the flags for consistency and create the database
  // directory if it doesn't exist.
  if (!OpenFileFlagsAreConsistent(desired_flags) ||
      !base::CreateDirectory(file_path.DirName())) {
    return base::File();
  }

  int flags = 0;
  flags |= base::File::FLAG_READ;
  if (desired_flags & SQLITE_OPEN_READWRITE)
    flags |= base::File::FLAG_WRITE;

  if (!(desired_flags & SQLITE_OPEN_MAIN_DB))
    flags |= base::File::FLAG_EXCLUSIVE_READ | base::File::FLAG_EXCLUSIVE_WRITE;

  flags |= ((desired_flags & SQLITE_OPEN_CREATE) ?
           base::File::FLAG_OPEN_ALWAYS : base::File::FLAG_OPEN);

  if (desired_flags & SQLITE_OPEN_EXCLUSIVE)
    flags |= base::File::FLAG_EXCLUSIVE_READ | base::File::FLAG_EXCLUSIVE_WRITE;

  if (desired_flags & SQLITE_OPEN_DELETEONCLOSE) {
    flags |= base::File::FLAG_TEMPORARY | base::File::FLAG_HIDDEN |
             base::File::FLAG_DELETE_ON_CLOSE;
  }

  // This flag will allow us to delete the file later on from the browser
  // process.
  flags |= base::File::FLAG_SHARE_DELETE;

  // Try to open/create the DB file.
  return base::File(file_path, flags);
}

// static
base::File VfsBackend::OpenTempFileInDirectory(const base::FilePath& dir_path,
                                               int desired_flags) {
  // We should be able to delete temp files when they're closed
  // and create them as needed
  if (!(desired_flags & SQLITE_OPEN_DELETEONCLOSE) ||
      !(desired_flags & SQLITE_OPEN_CREATE)) {
    return base::File();
  }

  // Get a unique temp file name in the database directory.
  base::FilePath temp_file_path;
  if (!base::CreateTemporaryFileInDir(dir_path, &temp_file_path))
    return base::File();

  return OpenFile(temp_file_path, desired_flags);
}

// static
int VfsBackend::DeleteFile(const base::FilePath& file_path, bool sync_dir) {
  if (!base::PathExists(file_path))
    return SQLITE_OK;
  if (!base::DeleteFile(file_path, false))
    return SQLITE_IOERR_DELETE;

  int error_code = SQLITE_OK;
#if defined(OS_POSIX)
  if (sync_dir) {
    base::File dir(file_path.DirName(), base::File::FLAG_READ);
    if (dir.IsValid()) {
      if (!dir.Flush())
        error_code = SQLITE_IOERR_DIR_FSYNC;
    } else {
      error_code = SQLITE_CANTOPEN;
    }
  }
#endif
  return error_code;
}

// static
uint32 VfsBackend::GetFileAttributes(const base::FilePath& file_path) {
#if defined(OS_WIN)
  uint32 attributes = ::GetFileAttributes(file_path.value().c_str());
#elif defined(OS_POSIX)
  uint32 attributes = 0;
  if (!access(file_path.value().c_str(), R_OK))
    attributes |= static_cast<uint32>(R_OK);
  if (!access(file_path.value().c_str(), W_OK))
    attributes |= static_cast<uint32>(W_OK);
  if (!attributes)
    attributes = -1;
#endif
  return attributes;
}

// static
int64 VfsBackend::GetFileSize(const base::FilePath& file_path) {
  int64 size = 0;
  return (base::GetFileSize(file_path, &size) ? size : 0);
}

// static
bool VfsBackend::SetFileSize(const base::FilePath& file_path, int64 size) {
  int flags = 0;
  flags |= base::File::FLAG_READ;
  flags |= base::File::FLAG_WRITE;
  flags |= base::File::FLAG_OPEN;
  base::File file = base::File(file_path, flags);
  if (!file.IsValid())
    return false;
  return file.SetLength(size);
}

}  // namespace storage
