"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Primitive_1 = require("../../../../Primitive");
const storage_1 = require("../../../../client/util/storage");
const MethodNotImplementedError_1 = require("../../../../exception/MethodNotImplementedError");
const ObjectPathTooDeep_1 = require("../../../../exception/ObjectPathTooDeep");
class Storage_ extends Primitive_1.Primitive {
    constructor(system, id, prefix) {
        super({
            i: [],
            o: [],
        }, {}, system, id);
        this._storage = () => {
            throw new MethodNotImplementedError_1.MethodNotImplementedError();
        };
        this._prefix = prefix;
    }
    read() {
        const { path } = this.__system;
        const storage = this._storage();
        const data = (0, storage_1.read)(storage, path);
        return data;
    }
    write(data) {
        const { path } = this.__system;
        const storage = this._storage();
        (0, storage_1.write)(storage, path, data);
    }
    get(name) {
        const { path } = this.__system;
        const storage = this._storage();
        return (0, storage_1.get)(storage, path, name);
    }
    set(name, data) {
        const { path, emitter } = this.__system;
        const storage = this._storage();
        (0, storage_1.set)(storage, path, name, data);
        emitter.emit(`${this._prefix}_storage`, name, data);
    }
    delete(name) {
        const { path, emitter } = this.__system;
        const storage = this._storage();
        (0, storage_1.delete_)(storage, path, name);
        emitter.emit(`${this._prefix}_storage`, name, undefined);
    }
    deepSet(path_, data) {
        const { path } = this.__system;
        const storage = this._storage();
        if (path_.length > 0) {
            throw new ObjectPathTooDeep_1.ObjectPathTooDeepError();
        }
        return (0, storage_1.set)(storage, path_[0], data, path);
    }
    deepGet(path_) {
        const { path } = this.__system;
        const storage = this._storage();
        if (path_.length > 0) {
            throw new ObjectPathTooDeep_1.ObjectPathTooDeepError();
        }
        return (0, storage_1.get)(storage, path, path_[0]);
    }
    deepDelete(path_) {
        const { path } = this.__system;
        const storage = this._storage();
        if (path_.length > 1) {
            throw new ObjectPathTooDeep_1.ObjectPathTooDeepError();
        }
        return (0, storage_1.delete_)(storage, path, path_[0]);
    }
    deepHas(path) {
        try {
            this.deepGet(path);
            return true;
        }
        catch (err) {
            return false;
        }
    }
    subscribe(path, key, listener) {
        const { emitter } = this.__system;
        if (path.length > 0) {
            throw new ObjectPathTooDeep_1.ObjectPathTooDeepError();
        }
        return emitter.addListener(`${this._prefix}_storage`, (key_, value) => {
            if (key_ === key || key === '*') {
                if (value === undefined) {
                    listener('delete', [], key, value);
                }
                else {
                    listener('set', [], key, value);
                }
            }
        });
    }
    keys() {
        const { path } = this.__system;
        const storage = this._storage();
        return (0, storage_1.keys)(storage, path);
    }
    hasKey(name) {
        const { path } = this.__system;
        const storage = this._storage();
        const has = (0, storage_1.hasKey)(storage, path, name);
        return has;
    }
}
exports.default = Storage_;
//# sourceMappingURL=Storage_.js.map