// Copyright (c) 2018 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.

class DatabaseUtils {
  /** Wrap an IndexedDB request into a Promise.
   *
   * This should not be used for open().
   *
   * @param {IDBRequest} request the request to be wrapped
   * @returns {Promise<Object>} promise that resolves with the request's result,
   *     or rejects with an error
   */
  static async promiseForRequest(request) {
    return new Promise((resolve, reject) => {
      request.onsuccess = event => { resolve(event.target.result); };
      request.onerror = event => { reject(event.target.error); };
      request.onblocked = event => {
        reject(event.target.error ||
                (new Error("blocked by other database connections")));
      };
      request.onupgradeneeded = event => {
        reject(event.target.error ||
                (new Error("unexpected upgradeneeded event")));
      };
    });
  }

  /** Wrap an IndexedDB database open request into a Promise.
   *
   * This is intended to be used by open().
   *
   * @param {IDBOpenDBRequest} request the request to be wrapped
   * @returns {Promise<{database: idbDatabase, transaction: IDBTransaction?}>}
   *     promise that resolves with an object whose "database" property is the
   *     newly opened database; if an upgradeneeded event is received, the
   *     "transaction" property holds the upgrade transaction
   */
  static async promiseForOpenRequest(request) {
    return new Promise((resolve, reject) => {
      request.onsuccess = event => {
        resolve({ database: event.target.result, transaction: null });
      };
      request.onerror = event => { reject(event.target.error); };
      request.onblocked = event => {
        reject(event.target.error ||
                (new Error("blocked by other database connections")));
      };
      request.onupgradeneeded = event => {
        resolve({
          database: event.target.result,
          transaction: event.target.transaction
        });
      };
    });
  }

  /** Wrap an IndexedDB transaction into a Promise.
   *
   * @param {IDBTransaction} transaction the transaction to be wrapped
   * @returns {Promise<Object>} promise that resolves with undefined when the
   *     transaction is completed, or rejects with an error if the transaction
   *     is aborted or errors out
   */
  static async promiseForTransaction(transaction) {
    return new Promise((resolve, reject) => {
      transaction.oncomplete = () => { resolve(); };
      transaction.onabort = event => { reject(event.target.error); };
      transaction.onerror = event => { reject(event.target.error); };
    });
  }
}

class Database {
  /** Open a database.
   *
   * @param {string} dbName the name of the database to be opened
   * @return {Promise<Database>} promise that resolves with a new Database
   *     instance for the open database
   */
  static async open(dbName) {
    const request = indexedDB.open(dbName, 1);
    const result = await DatabaseUtils.promiseForOpenRequest(request);

    if (result.transaction !== null) {
      fail("expected db to exist");
      return;
    }

    return new Database(dbName, result.database);
  }

  /** Do not instantiate directly. Use Database.open() instead.
   *
   * @param {string} dbName the database's name
   * @param {IDBDatabase} idbDatabase the IndexedDB instance wrapped by this
   */
  constructor(dbName, idbDatabase) {
    this._dbName = dbName;
    this._idbDatabase = idbDatabase;
  }

  /** Closes the underlying database. All future operations will fail. */
  close() {
    this._idbDatabase.close();
  }

  /** Reads from a store by iterating a cursor.
   *
   * @param {string} storeName the name of the store being read
   * @param {{index?: string, range?: IDBKeyRange}} query narrows down the data
   *     being read
   * @param {function(IDBCursor): boolean} cursorCallback called for each cursor
   *     yielded by the iteration; must return a truthy value to continue
   *     iteration, or a falsey value to stop iterating
   */
  async iterateCursor(storeName, query, cursorCallback) {
    const transaction = this._idbDatabase.transaction([storeName], 'readonly');
    const transactionPromise = DatabaseUtils.promiseForTransaction(transaction);

    const objectStore = transaction.objectStore(storeName);
    const dataSource = ('index' in query) ? objectStore.index(query.index)
                                          : objectStore;
    const request = ('range' in query) ? dataSource.openCursor(query.range)
                                        : dataSource.openCursor();
    while (true) {
      const cursor = await DatabaseUtils.promiseForRequest(request);
      if (!cursor)
        break;  // The iteration completed.

      const willContinue = cursorCallback(cursor);
      if (!willContinue)
        break;
      cursor.continue();
    }

    await transactionPromise;
    return true;
  }

  async read() {
    const status = document.getElementById('status');
    status.textContent = 'Started reading items';

    let i = 0;
    const result = await this.iterateCursor('store', {}, cursor => {
      i += 1;
      if (cursor.primaryKey !== i) {
        status.textContent =
            `Incorrect primaryKey - wanted ${i} got ${cursor.primaryKey}`;
        return false;
      }
      if (cursor.key !== i) {
        status.textContent = `Incorrect key - wanted ${i} got ${cursor.key}`;
        return false;
      }
      if (cursor.value.id !== i) {
        status.textContent =
            `Incorrect value.id - wanted ${i} got ${cursor.key}`;
        return false;
      }
      return true;
    });
    if (!result) {
      status.textContent = `Failed to read items`;
      return false;
    }
    status.textContent = `Done reading ${i} items`;
    return true;
  }
};
