import Signal from "../../events/signal/Signal.js";

/**
 * Decorator that wraps another map and lets you observe mutations
 * @template K,V
 */
export class ObservedMap {
    /**
     * @readonly
     */
    on = {
        /**
         * @type {Signal}
         */
        set: new Signal(),
        /**
         * @type {Signal}
         */
        deleted: new Signal()
    };

    /**
     * @template K,V
     * @constructor
     */
    constructor(source = new Map()) {

        /**
         *
         * @type {Map<K, V>}
         */
        this.data = source;
    }

    /**
     *
     * @param {K} key
     * @return {boolean}
     */
    has(key){
        return this.data.has(key);
    }

    /**
     *
     * @param {K} key
     * @returns {V|undefined}
     */
    get(key) {
        return this.data.get(key);
    }

    /**
     *
     * @param {K} key
     * @param {V} value
     * @returns {ObservedMap}
     */
    set(key, value) {
        this.data.set(key, value);
        this.on.set.send2(key, value);

        return this;
    }

    /**
     *
     * @param {K} key
     * @returns {boolean}
     */
    delete(key) {
        const result = this.data.delete(key);

        if (result) {
            this.on.deleted.send1(key);
        }

        return result;
    }

    /**
     * Implements {@link Map#forEach} interface
     * @param {function} callback
     * @param {*} [thisArg]
     */
    forEach(callback, thisArg) {
        this.data.forEach(callback, thisArg);
    }

    /**
     *
     * @return {number}
     */
    get size() {
        return this.data.size;
    }
}
