// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { Constants } from "../common/index.js";
import { startBackgroundTask } from "../utils/time.js";
/**
 * Class to store encryption keys in unwrapped form and provide an interface for wrapping and unwrapping the keys.
 */
export class EncryptionKeyStoreProvider {
    keyEncryptionKeyResolver;
    cacheTimeToLive;
    RsaOaepEncryptionAlgorithm = "RSA-OAEP";
    // interval for clear cache to run
    cacheRefresher;
    // cache to store the unwrapped encryption key. Key is the path of the encryption key
    unwrappedEncryptionKeyCache;
    providerName;
    constructor(keyEncryptionKeyResolver, cacheTimeToLive) {
        this.keyEncryptionKeyResolver = keyEncryptionKeyResolver;
        this.cacheTimeToLive = cacheTimeToLive;
        this.keyEncryptionKeyResolver = keyEncryptionKeyResolver;
        this.providerName = keyEncryptionKeyResolver.encryptionKeyResolverName;
        this.unwrappedEncryptionKeyCache = {};
        this.cacheTimeToLive = cacheTimeToLive;
        this.clearCacheOnTtlExpiry();
    }
    async wrapKey(encryptionKeyId, algorithm, key) {
        const uInt8ArrayKey = new Uint8Array(key);
        const wrappedEncryptionKey = await this.keyEncryptionKeyResolver.wrapKey(encryptionKeyId, algorithm, uInt8ArrayKey);
        return Buffer.from(wrappedEncryptionKey);
    }
    async unwrapKey(encryptionKeyId, algorithm, wrappedKey) {
        if (this.cacheTimeToLive === 0) {
            const res = await this.keyEncryptionKeyResolver.unwrapKey(encryptionKeyId, algorithm, wrappedKey);
            return Buffer.from(res);
        }
        if (!this.unwrappedEncryptionKeyCache[encryptionKeyId]) {
            const wrappedKeyUint8Array = new Uint8Array(wrappedKey);
            const plainEncryptionKey = await this.keyEncryptionKeyResolver.unwrapKey(encryptionKeyId, algorithm, wrappedKeyUint8Array);
            const plainEncryptionKeyBuffer = Buffer.from(plainEncryptionKey);
            this.unwrappedEncryptionKeyCache[encryptionKeyId] = [new Date(), plainEncryptionKeyBuffer];
        }
        return this.unwrappedEncryptionKeyCache[encryptionKeyId][1];
    }
    async clearCacheOnTtlExpiry() {
        this.cacheRefresher = startBackgroundTask(async () => {
            const now = new Date();
            for (const key in this.unwrappedEncryptionKeyCache) {
                if (now.getTime() - this.unwrappedEncryptionKeyCache[key][0].getTime() >
                    this.cacheTimeToLive) {
                    delete this.unwrappedEncryptionKeyCache[key];
                }
            }
        }, Constants.EncryptionCacheRefreshIntervalInMs);
    }
}
//# sourceMappingURL=EncryptionKeyStoreProvider.js.map