import isIdentical from '../Array/isIdentical';

const cache = new Map();

/**
 * A helper function to cache results of expensive functions (an alternative way of memoize)
 * @param {string} name
 * @param {...*} args
 */
export function getCached(name, ...args) {
    const cachedItem = cache.get(name);
    const isValid = Boolean(cachedItem && isIdentical(args, cachedItem.args));

    return {
        /**
         * @return {boolean}
         */
        validate() {
            return isValid;
        },
        /**
         * @return {*}
         */
        getValue() {
            return (isValid && cachedItem.value) || undefined;
        },
        /**
         * @param {*} value
         */
        setValue(value) {
            cache.set(name, {
                args,
                value,
            });
            return value;
        },
        /**
         * @param fn
         * @return {*}
         */
        use(fn) {
            if (this.validate()) {
                return this.getValue();
            }
            return this.setValue(fn());
        },
    };
}
