import '@sd-angular/core/common';
import { __classPrivateFieldGet, __awaiter } from 'tslib';
import { InjectionToken, ɵɵdefineInjectable, ɵɵinject, Injectable, Inject, Optional } from '@angular/core';
import hash from 'object-hash';
import { BehaviorSubject } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';

const CACHE_CONFIG = new InjectionToken('cache.configuration');

var _cache, _subject, _get, _getServer, _set, _setServer, _has, _hasServer, _remove, _removeServer;
class SdCacheService {
    constructor(configuration) {
        this.configuration = configuration;
        _cache.set(this, {});
        _subject.set(this, {});
        _get.set(this, (key, option) => {
            return () => {
                let cache = __classPrivateFieldGet(this, _cache)[key];
                if ((option === null || option === void 0 ? void 0 : option.type) === 'session') {
                    try {
                        cache = JSON.parse(sessionStorage.getItem(key));
                    }
                    catch (_a) {
                        cache = undefined;
                    }
                }
                if ((option === null || option === void 0 ? void 0 : option.type) === 'local') {
                    try {
                        cache = JSON.parse(localStorage.getItem(key));
                    }
                    catch (_b) {
                        cache = undefined;
                    }
                }
                if (!cache) {
                    return option === null || option === void 0 ? void 0 : option.default;
                }
                if ((option === null || option === void 0 ? void 0 : option.hours) && Date.addHours(cache.createdOn, option === null || option === void 0 ? void 0 : option.hours) < new Date()) {
                    const remove = __classPrivateFieldGet(this, _remove).call(this, key, option);
                    remove();
                    return option === null || option === void 0 ? void 0 : option.default;
                }
                return JSON.parse(JSON.stringify(cache.data));
            };
        });
        _getServer.set(this, (key, option) => {
            return () => __awaiter(this, void 0, void 0, function* () {
                var _a;
                let cache = __classPrivateFieldGet(this, _cache)[key];
                if ((_a = this.configuration) === null || _a === void 0 ? void 0 : _a.get) {
                    cache = yield this.configuration.get(key, option).catch(err => {
                        console.error(err);
                        return undefined;
                    });
                }
                if (!cache) {
                    return option === null || option === void 0 ? void 0 : option.default;
                }
                if ((option === null || option === void 0 ? void 0 : option.hours) && Date.addHours(cache.createdOn, option === null || option === void 0 ? void 0 : option.hours) < new Date()) {
                    const remove = __classPrivateFieldGet(this, _removeServer).call(this, key, option);
                    remove();
                    return option === null || option === void 0 ? void 0 : option.default;
                }
                return JSON.parse(JSON.stringify(cache.data));
            });
        });
        _set.set(this, (key, option) => {
            return (data) => {
                data = data !== null && data !== void 0 ? data : null;
                __classPrivateFieldGet(this, _cache)[key] = {
                    data: JSON.parse(JSON.stringify(data)),
                    createdOn: new Date()
                };
                if ((option === null || option === void 0 ? void 0 : option.type) === 'session') {
                    try {
                        sessionStorage.setItem(key, JSON.stringify(__classPrivateFieldGet(this, _cache)[key]));
                    }
                    catch (err) {
                        console.error(err);
                    }
                }
                if ((option === null || option === void 0 ? void 0 : option.type) === 'local') {
                    try {
                        localStorage.setItem(key, JSON.stringify(__classPrivateFieldGet(this, _cache)[key]));
                    }
                    catch (err) {
                        console.error(err);
                    }
                }
                __classPrivateFieldGet(this, _subject)[key].next(__classPrivateFieldGet(this, _cache)[key].data);
            };
        });
        _setServer.set(this, (key, option) => {
            return (data) => __awaiter(this, void 0, void 0, function* () {
                var _a;
                data = data !== null && data !== void 0 ? data : null;
                __classPrivateFieldGet(this, _cache)[key] = {
                    data: JSON.parse(JSON.stringify(data)),
                    createdOn: new Date()
                };
                if ((_a = this.configuration) === null || _a === void 0 ? void 0 : _a.set) {
                    try {
                        yield this.configuration.set(key, __classPrivateFieldGet(this, _cache)[key], option);
                    }
                    catch (err) {
                        console.error(err);
                    }
                }
                __classPrivateFieldGet(this, _subject)[key].next(__classPrivateFieldGet(this, _cache)[key].data);
            });
        });
        _has.set(this, (key, option) => {
            return () => {
                let cache = __classPrivateFieldGet(this, _cache)[key];
                if ((option === null || option === void 0 ? void 0 : option.type) === 'session') {
                    try {
                        cache = JSON.parse(sessionStorage.getItem(key));
                    }
                    catch (_a) {
                        cache = undefined;
                    }
                }
                if ((option === null || option === void 0 ? void 0 : option.type) === 'local') {
                    try {
                        cache = JSON.parse(localStorage.getItem(key));
                    }
                    catch (_b) {
                        cache = undefined;
                    }
                }
                if (!cache) {
                    return false;
                }
                if ((option === null || option === void 0 ? void 0 : option.hours) && Date.addHours(cache.createdOn, option === null || option === void 0 ? void 0 : option.hours) < new Date()) {
                    return false;
                }
                return true;
            };
        });
        _hasServer.set(this, (key, option) => {
            return () => __awaiter(this, void 0, void 0, function* () {
                var _a;
                let cache = __classPrivateFieldGet(this, _cache)[key];
                if ((_a = this.configuration) === null || _a === void 0 ? void 0 : _a.get) {
                    cache = yield this.configuration.get(key, option).catch(err => {
                        console.error(err);
                        return undefined;
                    });
                }
                if (!cache) {
                    return false;
                }
                if ((option === null || option === void 0 ? void 0 : option.hours) && Date.addHours(cache.createdOn, option === null || option === void 0 ? void 0 : option.hours) < new Date()) {
                    return false;
                }
                return true;
            });
        });
        _remove.set(this, (key, option) => {
            return () => {
                __classPrivateFieldGet(this, _cache)[key] = undefined;
                if ((option === null || option === void 0 ? void 0 : option.type) === 'session') {
                    sessionStorage.removeItem(key);
                }
                if ((option === null || option === void 0 ? void 0 : option.type) === 'local') {
                    localStorage.removeItem(key);
                }
                __classPrivateFieldGet(this, _subject)[key].next(undefined);
            };
        });
        _removeServer.set(this, (key, option) => {
            return () => __awaiter(this, void 0, void 0, function* () {
                var _a;
                __classPrivateFieldGet(this, _cache)[key] = undefined;
                if ((_a = this.configuration) === null || _a === void 0 ? void 0 : _a.remove) {
                    yield this.configuration.remove(key, option).catch(err => {
                        console.error(err);
                    });
                }
                __classPrivateFieldGet(this, _subject)[key].next(undefined);
            });
        });
    }
    create(key, option) {
        if (!key) {
            throw new Error('Key is required');
        }
        let hashKey = null;
        if (typeof (key) === 'string') {
            hashKey = key;
        }
        else if (typeof (key) === 'object') {
            hashKey = hash(key);
        }
        else {
            throw new Error('Invalid key');
        }
        if (!__classPrivateFieldGet(this, _subject)[hashKey]) {
            __classPrivateFieldGet(this, _subject)[hashKey] = new BehaviorSubject(option === null || option === void 0 ? void 0 : option.default);
        }
        const get = __classPrivateFieldGet(this, _get).call(this, hashKey, option);
        const set = __classPrivateFieldGet(this, _set).call(this, hashKey, option);
        const has = __classPrivateFieldGet(this, _has).call(this, hashKey, option);
        const remove = __classPrivateFieldGet(this, _remove).call(this, hashKey, option);
        return {
            get,
            set,
            has,
            remove,
            observer: __classPrivateFieldGet(this, _subject)[hashKey].pipe(map(get))
        };
    }
    createServer(key, option) {
        if (!key) {
            throw new Error('Key is required');
        }
        let hashKey = null;
        if (typeof (key) === 'string') {
            hashKey = key;
        }
        else if (typeof (key) === 'object') {
            hashKey = hash(key);
        }
        else {
            throw new Error('Invalid key');
        }
        if (!__classPrivateFieldGet(this, _subject)[hashKey]) {
            __classPrivateFieldGet(this, _subject)[hashKey] = new BehaviorSubject(option === null || option === void 0 ? void 0 : option.default);
        }
        const get = __classPrivateFieldGet(this, _getServer).call(this, hashKey, option);
        const set = __classPrivateFieldGet(this, _setServer).call(this, hashKey, option);
        const has = __classPrivateFieldGet(this, _hasServer).call(this, hashKey, option);
        const remove = __classPrivateFieldGet(this, _removeServer).call(this, hashKey, option);
        return {
            get,
            set,
            has,
            remove,
            observer: __classPrivateFieldGet(this, _subject)[hashKey].pipe(switchMap(get))
        };
    }
}
_cache = new WeakMap(), _subject = new WeakMap(), _get = new WeakMap(), _getServer = new WeakMap(), _set = new WeakMap(), _setServer = new WeakMap(), _has = new WeakMap(), _hasServer = new WeakMap(), _remove = new WeakMap(), _removeServer = new WeakMap();
SdCacheService.ɵprov = ɵɵdefineInjectable({ factory: function SdCacheService_Factory() { return new SdCacheService(ɵɵinject(CACHE_CONFIG, 8)); }, token: SdCacheService, providedIn: "root" });
SdCacheService.decorators = [
    { type: Injectable, args: [{
                providedIn: 'root'
            },] }
];
SdCacheService.ctorParameters = () => [
    { type: undefined, decorators: [{ type: Inject, args: [CACHE_CONFIG,] }, { type: Optional }] }
];

/**
 * Generated bundle index. Do not edit.
 */

export { CACHE_CONFIG, SdCacheService };
//# sourceMappingURL=sd-angular-core-cache.js.map
