// Copyright 2016 Google Inc. 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.

// Adapted from cobalt/storage.

#include "sql/test_vfs.h"

#include <string.h>

#include <algorithm>
#include <map>

#include "base/compiler_specific.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/rand_util.h"
#include "base/string_util.h"
#include "base/synchronization/lock.h"
#include "third_party/sqlite/sqlite3.h"

namespace sql {

namespace {

// A "subclass" of sqlite3_file with our required data structures added.
struct virtual_file {
  sqlite3_file sql_internal_file;
  std::string* data;
  base::Lock* lock;
  int current_lock;
  int shared;
};

// A very simple in-memory virtual file system.
class TestVfs {
 public:
  typedef std::map<std::string, std::string> FileMap;

 public:
  TestVfs() {}
  ~TestVfs() {}

  void Register();
  void Unregister();

  std::string* Open(const char* path) {
    return &file_map_[path];
  }

  void Delete(const char* path) {
    file_map_.erase(path);
  }

 private:
  sqlite3_vfs vfs_;
  FileMap file_map_;
};

base::LazyInstance<TestVfs> g_vfs = LAZY_INSTANCE_INITIALIZER;

int VfsClose(sqlite3_file* file) {
  virtual_file* vfile = reinterpret_cast<virtual_file*>(file);
  delete vfile->lock;
  return SQLITE_OK;
}

int VfsRead(sqlite3_file* file, void* out, int bytes, sqlite_int64 offset) {
  virtual_file* vfile = reinterpret_cast<virtual_file*>(file);
  base::AutoLock lock(*vfile->lock);
  if (offset >= static_cast<sqlite_int64>(vfile->data->length())) {
    return SQLITE_OK;
  }

  size_t available =
      std::max(static_cast<sqlite_int64>(vfile->data->length()) - offset,
               static_cast<sqlite_int64>(0));
  size_t to_read = std::min(available, static_cast<size_t>(bytes));
  if (to_read == 0) {
    return SQLITE_OK;
  }

  memcpy(out, &(vfile->data->c_str()[offset]), to_read);
  return SQLITE_OK;
}

int VfsWrite(sqlite3_file* file,
             const void* data,
             int bytes,
             sqlite3_int64 offset) {
  size_t max = offset + bytes;

  virtual_file* vfile = reinterpret_cast<virtual_file*>(file);
  base::AutoLock lock(*vfile->lock);
  if (vfile->data->length() < max) {
    vfile->data->resize(max);
  }

  vfile->data->replace(offset, bytes, reinterpret_cast<const char*>(data),
                       bytes);

  return SQLITE_OK;
}

int VfsSync(sqlite3_file* pFile, int flags) {
  UNREFERENCED_PARAMETER(pFile);
  UNREFERENCED_PARAMETER(flags);
  return SQLITE_OK;
}

int VfsFileControl(sqlite3_file* pFile, int op, void* pArg) {
  UNREFERENCED_PARAMETER(pFile);
  UNREFERENCED_PARAMETER(op);
  UNREFERENCED_PARAMETER(pArg);
  return SQLITE_OK;
}

int VfsSectorSize(sqlite3_file* file) {
  // The number of bytes that can be read without disturbing other bytes in the
  // file.
  UNREFERENCED_PARAMETER(file);
  return 1;
}

int VfsLock(sqlite3_file* file, const int mode) {
  virtual_file* vfile = reinterpret_cast<virtual_file*>(file);
  base::AutoLock lock(*vfile->lock);

  // If there is already a lock of this type or more restrictive, do nothing
  if (vfile->current_lock >= mode) {
    return SQLITE_OK;
  }

  if (mode == SQLITE_LOCK_SHARED) {
    DCHECK_EQ(vfile->current_lock, SQLITE_LOCK_NONE);
    vfile->shared++;
    vfile->current_lock = SQLITE_LOCK_SHARED;
  }

  if (mode == SQLITE_LOCK_RESERVED) {
    DCHECK_EQ(vfile->current_lock, SQLITE_LOCK_SHARED);
    vfile->current_lock = SQLITE_LOCK_RESERVED;
  }

  if (mode == SQLITE_LOCK_EXCLUSIVE) {
    if (vfile->current_lock >= SQLITE_LOCK_PENDING) {
      return SQLITE_BUSY;
    }
    vfile->current_lock = SQLITE_LOCK_PENDING;
    if (vfile->shared > 1) {
      // There are some outstanding shared locks (greater than one because the
      // pending lock is an "upgraded" shared lock)
      return SQLITE_BUSY;
    }
    // Acquire the exclusive lock
    vfile->current_lock = SQLITE_LOCK_EXCLUSIVE;
  }

  return SQLITE_OK;
}

int VfsUnlock(sqlite3_file* file, int mode) {
  DCHECK_LE(mode, SQLITE_LOCK_SHARED);
  virtual_file* vfile = reinterpret_cast<virtual_file*>(file);
  base::AutoLock lock(*vfile->lock);

  COMPILE_ASSERT(SQLITE_LOCK_NONE < SQLITE_LOCK_SHARED,
                 sqlite_lock_constants_order_has_changed);
  COMPILE_ASSERT(SQLITE_LOCK_SHARED < SQLITE_LOCK_RESERVED,
                 sqlite_lock_constants_order_has_changed);
  COMPILE_ASSERT(SQLITE_LOCK_RESERVED < SQLITE_LOCK_PENDING,
                 sqlite_lock_constants_order_has_changed);
  COMPILE_ASSERT(SQLITE_LOCK_PENDING < SQLITE_LOCK_EXCLUSIVE,
                 sqlite_lock_constants_order_has_changed);

  if (mode == SQLITE_LOCK_NONE && vfile->current_lock >= SQLITE_LOCK_SHARED) {
    vfile->shared--;
  }

  vfile->current_lock = mode;
  return SQLITE_OK;
}

int VfsCheckReservedLock(sqlite3_file* file, int* result) {
  virtual_file* vfile = reinterpret_cast<virtual_file*>(file);
  base::AutoLock lock(*vfile->lock);

  // The function expects a result is 1 if the lock is reserved, pending, or
  // exclusive; 0 otherwise.
  *result = vfile->current_lock >= SQLITE_LOCK_RESERVED ? 1 : 0;
  return SQLITE_OK;
}

int VfsFileSize(sqlite3_file* file, sqlite3_int64* out_size) {
  virtual_file* vfile = reinterpret_cast<virtual_file*>(file);
  *out_size = vfile->data->length();
  return SQLITE_OK;
}

int VfsTruncate(sqlite3_file* file, sqlite3_int64 size) {
  virtual_file* vfile = reinterpret_cast<virtual_file*>(file);
  base::AutoLock lock(*vfile->lock);
  vfile->data->resize(size);
  return SQLITE_OK;
}

int VfsDeviceCharacteristics(sqlite3_file* file) {
  UNREFERENCED_PARAMETER(file);
  return 0;
}

const sqlite3_io_methods s_cobalt_vfs_io = {
    1,                        // Structure version number
    VfsClose,                 // xClose
    VfsRead,                  // xRead
    VfsWrite,                 // xWrite
    VfsTruncate,              // xTruncate
    VfsSync,                  // xSync
    VfsFileSize,              // xFileSize
    VfsLock,                  // xLock
    VfsUnlock,                // xUnlock
    VfsCheckReservedLock,     // xCheckReservedLock
    VfsFileControl,           // xFileControl
    VfsSectorSize,            // xSectorSize
    VfsDeviceCharacteristics  // xDeviceCharacteristics
};

int VfsOpen(sqlite3_vfs* sql_vfs,
            const char* path,
            sqlite3_file* file,
            int flags,
            int* out_flags) {
  UNREFERENCED_PARAMETER(flags);
  UNREFERENCED_PARAMETER(out_flags);
  DCHECK(path) << "NULL filename not supported.";
  virtual_file* vfile = reinterpret_cast<virtual_file*>(file);
  vfile->lock = new base::Lock;
  TestVfs* vfs = reinterpret_cast<TestVfs*>(sql_vfs->pAppData);
  vfile->data = vfs->Open(path);
  file->pMethods = &s_cobalt_vfs_io;
  return SQLITE_OK;
}

int VfsDelete(sqlite3_vfs* sql_vfs, const char* path, int sync_dir) {
  UNREFERENCED_PARAMETER(sync_dir);
  TestVfs* vfs = reinterpret_cast<TestVfs*>(sql_vfs->pAppData);
  vfs->Delete(path);
  return SQLITE_OK;
}

int VfsFullPathname(sqlite3_vfs* sql_vfs,
                    const char* path,
                    int out_size,
                    char* out_path) {
  UNREFERENCED_PARAMETER(sql_vfs);
  size_t path_size = static_cast<size_t>(out_size);
  if (base::strlcpy(out_path, path, path_size) < path_size) {
    return SQLITE_OK;
  }
  return SQLITE_ERROR;
}

int VfsAccess(sqlite3_vfs* sql_vfs, const char* name, int flags, int* result) {
  UNREFERENCED_PARAMETER(name);
  UNREFERENCED_PARAMETER(sql_vfs);
  UNREFERENCED_PARAMETER(flags);
  // We should always have a valid, readable/writable file.
  *result |= SQLITE_ACCESS_EXISTS | SQLITE_ACCESS_READWRITE;
  return SQLITE_OK;
}

int VfsRandomness(sqlite3_vfs* sql_vfs, int bytes, char* out) {
  UNREFERENCED_PARAMETER(sql_vfs);
  base::RandBytes(out, static_cast<size_t>(bytes));
  return SQLITE_OK;
}

void TestVfs::Register() {
  memset(&vfs_, 0, sizeof(vfs_));
  vfs_.iVersion = 1;
  vfs_.szOsFile = sizeof(virtual_file);
  vfs_.mxPathname = 512;
  vfs_.pNext = NULL;
  vfs_.zName = "test_vfs";
  vfs_.pAppData = this;
  vfs_.xOpen = VfsOpen;
  vfs_.xDelete = VfsDelete;
  vfs_.xAccess = VfsAccess;
  vfs_.xFullPathname = VfsFullPathname;
  vfs_.xRandomness = VfsRandomness;

  // Ensure we are not registering multiple of these with the same name.
  // Behavior is undefined in that case.
  DCHECK(sqlite3_vfs_find(vfs_.zName) == NULL);

  int ret = sqlite3_vfs_register(&vfs_, 1 /* make_default */);
  DCHECK_EQ(ret, SQLITE_OK);
}

void TestVfs::Unregister() {
  int ret = sqlite3_vfs_unregister(&vfs_);
  file_map_.clear();
  DCHECK_EQ(ret, SQLITE_OK);
}

}  // namespace

void RegisterTestVfs() {
  g_vfs.Get().Register();
}

void UnregisterTestVfs() {
  g_vfs.Get().Unregister();
}

}  // namespace sql
