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

module blink.mojom;

import "mojo/public/mojom/base/string16.mojom";
import "mojo/public/mojom/base/string16.mojom";
import "mojo/public/mojom/base/time.mojom";
import "third_party/blink/public/mojom/blob/blob.mojom";
import "third_party/blink/public/mojom/file_system_access/file_system_access_transfer_token.mojom";

// kIDBMaxMessageSize is 128MB, originally based on
// IPC::Channel::kMaximumMessageSize.  The "usable" size is this value less
// the overhead size.
const int32 kIDBMaxMessageSize = 134217728;

// kIDBMaxMessageOverhead is the size we expect to be used for the rest of
// the message we will send.  The "usable" size is the max size less this value.
const int32 kIDBMaxMessageOverhead = 1048576;  // 1MB; arbitrarily chosen.

// Default threshold for IDBValueWrapper::WrapIfBiggerThan().
//
// This should be tuned to achieve a compromise between short-term IndexedDB
// throughput and long-term I/O load and memory usage. LevelDB, the underlying
// storage for IndexedDB, was not designed with large values in mind. At the
// very least, large values will slow down compaction, causing occasional I/O
// spikes.
const int32 kIDBWrapThreshold = 65536;

// To avoid GetAll returning too much data in one mojo message, it is returned
// in chunks of keys or values.  This constant is the max number of keys/values
// returned per IDBDatabaseGetAllResultSink::Receive call.
const int32 kIDBGetAllChunkSize = 1000;

enum IDBCursorDirection {
  Next,
  NextNoDuplicate,
  Prev,
  PrevNoDuplicate,
};

enum IDBDataLoss {
  None,
  Total,
};

// In order of the least to the highest precedent in terms of sort order.
enum IDBKeyType {
  // Invalid is used in blink bindings code. When converting a V8 value that
  // is not a valid key, key of this type is returned. Outside of testing
  // it should only be used in blink code.
  Invalid,

  // The following indicate the type of a valid key, per the standard:
  // https://w3c.github.io/IndexedDB/#key-construct
  Array,
  Binary,
  String,
  Date,
  Number,

  // None is used to represent the lack of a key, e.g. when a key range
  // has no upper/lower bound.
  // TODO(jsbell): Consider using Optional<> instead.
  None,

  // Min is used to encode the lower bound of a construct in leveldb, e.g.
  // all entries in a store are in [{id, min}, {id+1, min}). It should
  // only appear in browser code.
  Min,
};

// Durability guarantees during a transaction.  This maps to whether or not
// the writes to disk are explicitly flushed or not.
enum IDBTransactionDurability {
  // Unspecified by caller, and so is implementation defined.
  // May map to either Strict or Relaxed.
  Default,

  // Always flush to disk after a write.
  Strict,

  // Do not flush to disk.  This is much faster.
  Relaxed,
};

union IDBKey {
  array<IDBKey> key_array;
  array<uint8> binary;
  mojo_base.mojom.String16 string;
  double date;
  double number;
  // TODO(jsbell): Consider using Optional<> instead.
  bool other_none;
};

// In order of the least to the highest precedent in terms of sort order.
// These values are written to logs. New enum values can be added, but
// existing enums must never be renumbered or deleted and reused.
enum IDBKeyPathType {
  Null,
  String,
  Array,
};

// Represents WebIDBKeyPathTypeString and WebIDBKeyPathTypeArray in a key path.
union IDBKeyPathData {
  mojo_base.mojom.String16 string;
  array<mojo_base.mojom.String16> string_array;
};

struct IDBKeyPath {
  // A null value here corresponds to WebIDBKeyPathTypeNull.
  IDBKeyPathData? data;
};

struct IDBKeyRange {
  IDBKey lower;
  IDBKey upper;
  bool lower_open;
  bool upper_open;
};

enum IDBOperationType {
  Add,
  Put,
  Delete,
  Clear,
};

enum IDBPutMode {
  AddOrUpdate,
  AddOnly,
  CursorUpdate,
};

enum IDBTaskType {
  Normal,
  Preemptive,
};

enum IDBTransactionMode {
  ReadOnly,
  ReadWrite,
  VersionChange,
};

enum IDBStatus {
  OK,
  NotFound,
  Corruption,
  NotSupported,
  InvalidArgument,
  IOError,
};

// These values need to match core/dom/exception_code.h
enum IDBException {
  kNoError = 0,
  kUnknownError = 28,
  kConstraintError = 29,
  kDataError = 30,
  kVersionError = 33,
  kAbortError = 20,
  kIgnorableAbortError = 11,
  kQuotaError = 22,
  kTimeoutError = 23,
};

struct IDBIndexMetadata {
  int64 id;
  mojo_base.mojom.String16 name;
  IDBKeyPath key_path;
  bool unique;
  bool multi_entry;
};

struct IDBObjectStoreMetadata {
  int64 id;
  mojo_base.mojom.String16 name;
  IDBKeyPath key_path;
  bool auto_increment;
  int64 max_index_id;
  map<int64, IDBIndexMetadata> indexes;
};

struct IDBDatabaseMetadata {
  int64 id;
  mojo_base.mojom.String16 name;
  int64 version;
  int64 max_object_store_id;
  map<int64, IDBObjectStoreMetadata> object_stores;
  bool was_cold_open;
};

struct IDBNameAndVersion {
  mojo_base.mojom.String16 name;
  int64 version;
};

struct IDBIndexKeys {
  int64 index_id;
  array<IDBKey> index_keys;
};

struct IDBFileInfo {
  mojo_base.mojom.String16 name;
  mojo_base.mojom.Time last_modified;
};

struct IDBBlobInfo {
  pending_remote<blink.mojom.Blob> blob;
  string uuid;
  mojo_base.mojom.String16 mime_type;
  int64 size;
  IDBFileInfo? file;
};

union IDBExternalObject {
  IDBBlobInfo blob_or_file;
  pending_remote<FileSystemAccessTransferToken> file_system_access_token;
};

struct IDBValue {
  array<uint8> bits;
  array<IDBExternalObject> external_objects;
};

struct IDBReturnValue {
  IDBValue value;
  IDBKey primary_key;
  IDBKeyPath key_path;
};

// The IDBCallbacks interface is used to return results for individual requests.
// Some requests may return multiple results before completion, such as
// UpgradeNeeded before SuccessDatabase.
//
// TODO(https://crbug.com/627484): Many of these could be replaced with
// replies associated with particular messages.
interface IDBCallbacks {
  Error(IDBException code, mojo_base.mojom.String16 message);

  // Factory::GetDatabaseInfo
  SuccessNamesAndVersionsList(array<IDBNameAndVersion> value);

  // Factory::Open / DeleteDatabase
  Blocked(int64 existing_version);

  // Factory::Open
  UpgradeNeeded(pending_associated_remote<IDBDatabase> pending_database,
                int64 old_version, IDBDataLoss data_loss,
                string data_loss_message, IDBDatabaseMetadata db_metadata);

  // Factory::Open
  SuccessDatabase(pending_associated_remote<IDBDatabase>? pending_database,
                  IDBDatabaseMetadata metadata);

  // Database::Count / DeleteRange
  // Factory::DeleteDatabase
  SuccessInteger(int64 value);

  // Cursor::Continue / Advance
  Success();
};

// The IDBDatabaseCallbacks interface is used to notification of events out of
// band to individual requests. A single instance is used for the lifetime of
// a database connection.
interface IDBDatabaseCallbacks {
  ForcedClose();
  VersionChange(int64 old_version, int64 new_version);
  Abort(int64 transaction_id, IDBException code,
        mojo_base.mojom.String16 message);
  Complete(int64 transaction_id);
};

struct IDBError {
  IDBException error_code;
  mojo_base.mojom.String16 error_message;
};

struct IDBCursorValue {
  array<IDBKey> keys;
  array<IDBKey> primary_keys;
  array<IDBValue> values;
};

union IDBCursorResult {
  IDBError error_result;  // |error| is reserved, so call this |error_result|.
  bool empty;  // False values are not allowed.
  IDBCursorValue values;
};

// Advance(), CursorContinue(), and Prefetch() can call its return callback in
// one of 3 ways:
// * with |error| set and |value| unset, if an error occurs
// * with |error| unset and |value| set, under normal operation
// * with |error| unset and |value| unset, under normal operation when the end
//   of the source being iterated is reached
interface IDBCursor {
  Advance(uint32 count) => (IDBCursorResult result);
  CursorContinue(IDBKey key, IDBKey primary_key) => (IDBCursorResult result);
  Prefetch(int32 count) => (IDBCursorResult result);
  PrefetchReset(int32 used_prefetches, int32 unused_prefetches);
};

union IDBTransactionPutResult {
  IDBError error_result;  // |error| is reserved, so call this |error_result|.
  IDBKey key;
};

union IDBTransactionPutAllResult {
  IDBError error_result;  // |error| is reserved, so call this |error_result|.
  array<IDBKey> keys;
};

struct IDBPutParams {
  IDBValue value;
  IDBKey key;
  array<IDBIndexKeys> index_keys;
};

interface IDBTransaction {
  CreateObjectStore(int64 object_store_id,
                    mojo_base.mojom.String16 name,
                    IDBKeyPath key_path,
                    bool auto_increment);
  DeleteObjectStore(int64 object_store_id);
  Put(int64 object_store_id,
      IDBValue value,
      IDBKey key,
      IDBPutMode mode,
      array<IDBIndexKeys> index_keys)
    => (IDBTransactionPutResult result);
  PutAll(int64 object_store_id,
    array<IDBPutParams> put_params)
    => (IDBTransactionPutAllResult result);
  Commit(int64 num_errors_handled);
};

union IDBDatabaseGetResult {
  IDBError error_result;  // |error| is reserved, so call this |error_result|.
  bool empty;  // False values are not allowed.
  IDBKey key;
  IDBReturnValue value;
};

// Result receiver type for GetAll to incrementally receive chunks of results.
// When the mojo connection disconnects, this signals that all of the results
// have been sent.
interface IDBDatabaseGetAllResultSink {
  // Incrementally receive some values.
  ReceiveValues(array<IDBReturnValue> values);

  // Incrementally receive some keys.
  ReceiveKeys(array<IDBKey> keys);

  // If any error occurs, call this function.  Once this function has been
  // called, ReceiveValues/ReceiveKeys should not be called again and
  // the entire result should be considered an error.
  OnError(IDBError error);
};

struct IDBDatabaseOpenCursorValue {
  pending_associated_remote<IDBCursor> cursor;
  IDBKey key;
  IDBKey primary_key;
  IDBValue? value;
};

union IDBDatabaseOpenCursorResult {
  IDBError error_result;  // |error| is reserved, so call this |error_result|.
  bool empty;  // Only true values are allowed.
  IDBDatabaseOpenCursorValue value;
};

interface IDBDatabase {
  RenameObjectStore(int64 transaction_id,
                    int64 object_store_id,
                    mojo_base.mojom.String16 new_name);
  CreateTransaction(pending_associated_receiver<IDBTransaction> transaction_receiver,
                    int64 transaction_id,
                    array<int64> object_store_ids,
                    IDBTransactionMode mode,
                    IDBTransactionDurability durability);
  Close();
  VersionChangeIgnored();
  Get(int64 transaction_id,
      int64 object_store_id,
      int64 index_id,
      IDBKeyRange key_range,
      bool key_only)
    => (IDBDatabaseGetResult result);
  GetAll(int64 transaction_id,
         int64 object_store_id,
         int64 index_id,
         IDBKeyRange key_range,
         bool key_only,
         int64 max_count)
    => (pending_receiver<IDBDatabaseGetAllResultSink> receiver);
  SetIndexKeys(int64 transaction_id,
               int64 object_store_id,
               IDBKey primary_key,
               array<IDBIndexKeys> index_keys);
  SetIndexesReady(int64 transaction_id,
                  int64 object_store_id,
                  array<int64> index_ids);
  OpenCursor(int64 transaction_id,
             int64 object_store_id,
             int64 index_id,
             IDBKeyRange key_range,
             IDBCursorDirection direction,
             bool key_only,
             IDBTaskType task_type)
    => (IDBDatabaseOpenCursorResult result);
  Count(int64 transaction_id,
        int64 object_store_id,
        int64 index_id,
        IDBKeyRange key_range,
        pending_associated_remote<IDBCallbacks> pending_callbacks);
  DeleteRange(int64 transaction_id,
              int64 object_store_id,
              IDBKeyRange key_range,
              pending_associated_remote<IDBCallbacks> pending_callbacks);
  // Gets the current number of an IndexedDB ObjectStore's key generator. It
  // is implemented in the browser (more priviledged) and handles requests in
  // the renderer process: WebIDBDatabaseImpl::GetKeyGeneratorCurrentNumber()
  GetKeyGeneratorCurrentNumber(int64 transaction_id,
                               int64 object_store_id,
                               pending_associated_remote<IDBCallbacks> pending_callbacks);
  Clear(int64 transaction_id,
        int64 object_store_id,
        pending_associated_remote<IDBCallbacks> pending_callbacks);
  CreateIndex(int64 transaction_id,
              int64 object_store_id,
              int64 index_id,
              mojo_base.mojom.String16 name,
              IDBKeyPath key_path,
              bool unique,
              bool multi_entry);
  DeleteIndex(int64 transaction_id,
              int64 object_store_id,
              int64 index_id);
  RenameIndex(int64 transaction_id,
              int64 object_store_id,
              int64 index_id,
              mojo_base.mojom.String16 new_name);
  Abort(int64 transaction_id);
};

interface IDBFactory {
  // Gets high level info about databases that exist in the frame's
  // origin. Posts results to |pending_callbacks|.
  GetDatabaseInfo(pending_associated_remote<IDBCallbacks> pending_callbacks);

  // Opens a database |name| in the frame's origin at version |version|.
  // |version_change_transaction_receiver| will have version change
  // transaction operations posted to it. |transaction_id| corresponds
  // to the transaction number for this connection's context.
  // Posts request events and results to |pending_callbacks| and database-level
  // events and results to |database_callbacks|.
  Open(pending_associated_remote<IDBCallbacks> pending_callbacks,
       pending_associated_remote<IDBDatabaseCallbacks> database_callbacks,
       mojo_base.mojom.String16 name,
       int64 version,
       pending_associated_receiver<IDBTransaction> version_change_transaction_receiver,
       int64 transaction_id);

  // Deletes a database |name| in the frame's origin. If |force_close|
  // is true, any existing connections to that database will be closed
  // immediately.
  DeleteDatabase(pending_associated_remote<IDBCallbacks> pending_callbacks,
                 mojo_base.mojom.String16 name, bool force_close);

  AbortTransactionsAndCompactDatabase() => (IDBStatus status);
  AbortTransactionsForDatabase() => (IDBStatus status);
};
