import { noop } from "../../core/function/noop.js";

class Storage {

    /**
     *
     * @param {string} key
     * @param {ArrayBuffer} value
     * @param {function} resolve
     * @param {function} reject
     * @param {function} progress
     */
    storeBinary(key, value, resolve, reject, progress) {
        //special case, delegate to generic by default
        this.store(key, value, resolve, reject, progress);
    }

    /**
     *
     * @param {string} key
     * @param {function(ArrayBuffer)} resolve
     * @param {function} reject
     * @param {function} progress
     */
    loadBinary(key, resolve, reject, progress) {
        //special case, delegate to generic by default
        this.load(key, resolve, reject, progress);
    }

    /**
     *
     * @param {string} key
     * @param {function} [progress]
     * @returns {Promise<ArrayBuffer>}
     */
    promiseLoadBinary(key, progress = noop) {
        return new Promise((resolve, reject) => {
            this.loadBinary(key, resolve, reject, progress);
        });
    }

    /**
     *
     * @param {string} key
     * @param {ArrayBuffer} value
     * @param {function} [progress]
     * @returns {Promise}
     */
    promiseStoreBinary(key, value, progress = noop) {
        return new Promise((resolve, reject) => {
            this.storeBinary(key, value, resolve, reject, progress);
        });
    }

    store(key, value, resolve, reject, progress) {
        throw new Error(`Not Implemented`);
    }

    load(key, resolve, reject, progress) {
        throw new Error(`Not Implemented`);
    }

    /**
     *
     * @param {function(list:string[])} resolve
     * @param {function} reject
     */
    list(resolve, reject) {
        throw new Error(`Not Implemented`);
    }

    /**
     *
     * @returns {Promise<string[]>}
     */
    promiseList() {
        return new Promise((resolve, reject) => this.list(resolve, reject));
    }

    /**
     *
     * @param {String} key
     * @param {function} resolve
     * @param {function} reject
     */
    remove(key, resolve, reject) {
        throw new Error('Not implemented');
    }

    /**
     *
     * @param {string} key
     * @returns {Promise<unknown>}
     */
    promiseRemove(key) {
        return new Promise((resolve, reject) => this.remove(key, resolve, reject));
    }

    /**
     *
     * @param {string} key
     * @param {function(boolean)} resolve
     * @param {function(reason:*)} reject
     */
    contains(key, resolve, reject) {
        let resolved = false;
        this.list(function (keys) {
            resolve(keys.indexOf(key) !== -1);
        }, reject);
    }

    /**
     *
     * @param {string} key
     * @returns {Promise<unknown>}
     */
    promiseContains(key) {
        return new Promise((resolve, reject) => this.contains(key, resolve, reject));
    }
}

export default Storage;
