// 模拟 CacheItemRemovedReason 枚举
enum CacheItemRemovedReason {
    DependencyChanged,
    Expired,
    Removed,
    Underused
}

class CacheManager {
    private static webCache: Storage = localStorage;

    static get GetWebCacheObj(): Storage {
        return this.webCache;
    }

    static GetCache(cacheKey: string): any {
        if (cacheKey.trim() === '') return null;
        const item = this.webCache.getItem(cacheKey);
        if (item) {
            const { value, expiration } = JSON.parse(item);
            if (expiration === null || Date.now() < expiration) {
                return value;
            } else {
                this.RemoveCache(cacheKey);
            }
        }
        return null;
    }

    static GetCacheWithFactory(cacheKey: string, valueFactory: (key: string) => any): any {
        if (cacheKey.trim() === '') return null;
        let ret = this.GetCache(cacheKey);
        if (ret === null) {
            ret = valueFactory(cacheKey);
            this.SetCache(cacheKey, ret);
        }
        return ret;
    }

    static SetCache(cacheKey: string, objObject: any, timeOut: number = 3600): void {
        if (cacheKey.trim() === '') return;
        const expiration = timeOut === 0 ? null : Date.now() + timeOut * 1000;
        const item = JSON.stringify({ value: objObject, expiration });
        this.webCache.setItem(cacheKey, item);
    }

    static RemoveCache(cacheKey: string): void {
        if (cacheKey.trim() === '') return;
        this.webCache.removeItem(cacheKey);
        this.onRemove(cacheKey, null, CacheItemRemovedReason.Removed);
    }

    static RemoveCacheByRegex(regexCacheKey: string): void {
        if (regexCacheKey.trim() === '') return;
        const reg = new RegExp(regexCacheKey);
        for (let i = 0; i < this.webCache.length; i++) {
            const cacheKey = this.webCache.key(i);
            if (cacheKey && reg.test(cacheKey)) {
                this.webCache.removeItem(cacheKey);
                this.onRemove(cacheKey, null, CacheItemRemovedReason.Removed);
            }
        }
    }

    private static onRemove(key: string, val: any, reason: CacheItemRemovedReason): void {
        switch (reason) {
            case CacheItemRemovedReason.DependencyChanged:
                break;
            case CacheItemRemovedReason.Expired:
                console.log(`[${key}]已过期`);
                break;
            case CacheItemRemovedReason.Removed:
                console.log(`[${key}]已移除`);
                break;
            case CacheItemRemovedReason.Underused:
                break;
            default:
                break;
        }
    }
}

export default CacheManager;