/*
 *  Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
 *  This source file is part of the Cangjie project, licensed under Apache-2.0
 *  with Runtime Library Exception.
 *
 *  See https://cangjie-lang.cn/pages/LICENSE for license information.
 */

package stdx.string_intern

/**
 * @brief  Encapsulates a simplified external cache.
 */
class CacheProxy<K, V> <: Cache<K, V> where K <: Hashable & Equatable<K> & ToString {
    protected var cache: ICache<K, V> = LRUMemoryCache<K, V>(cacheConfigs: DefaultCacheConfig())

    init(cacheConfig!: ICacheConfig = DefaultCacheConfig(),
                cacheKeyLinkList!: ILinkList<K> = ConcurrentSkipingLinkList<K>()) {
        var configOP: ?ICacheConfig = Some(cacheConfig)
        match (cacheConfig.evictionType) {
            case CacheEvictionType.LRU | CacheEvictionType.DEFAULT => cache = LRUMemoryCache<K, V>(
                    cacheConfigs: configOP,
                    cacheKeyLinkList: cacheKeyLinkList
            )
            case CacheEvictionType.FIFO => cache = FIFOMemoryCache<K, V>(
                    cacheConfigs: configOP,
                    cacheKeyLinkList: cacheKeyLinkList
            )
            case CacheEvictionType.LFU => cache = LFUMemoryCache<K, V>(cacheConfigs: configOP,
                    cacheKeyLinkList: cacheKeyLinkList)
            case _ => throw Exception("Unsupport cache eviction type.")
        }
    }

    public func putObject(key: K, value: V): Unit {
        this.cache.put(DefaultCacheObj(key, value))
    }

    public func clear() { // cjlint-ignore !G.DCL.02
        cache.removeAll()
    }

    public func getObject(key: K): ?V {
        var cacheObjOP: Option<ICacheObj<K, V>> = this.cache.get(key)
        if (let Some(cache) <- cacheObjOP) {
            return cache.value
        } else {
            return None
        }
    }

    public func removeObject(key: K): Unit {
        cache.remove(key)
    }

    public func initialize(cacheConfigs: ICacheConfig): Unit {
        cache.initialize(cacheConfigs)
    }

    public func size(): Int64 {
        return cache.getSize()
    }
}