"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.IcureStorageFacade = void 0;
const utils_1 = require("../crypto/utils");
/**
 * @internal This class is meant for internal use only and may be changed without notice.
 * Simplifies access to the storage facades for iCure-specific data storage.
 */
class IcureStorageFacade {
    constructor(keyStorage, storage, entryKeysFactory) {
        this.keys = keyStorage;
        this.data = storage;
        this.entryFor = entryKeysFactory;
    }
    /**
     * Saves a key pair for the data owner.
     * @param dataOwnerId id of the data owner with the key.
     * @param publicKeyFingerprint fingerprint of the public key of the pair.
     * @param keyPair a key pair of the data owner.
     * @param isDevice true if the key was generated on this device.
     */
    saveKey(dataOwnerId, publicKeyFingerprint, keyPair, isDevice) {
        return __awaiter(this, void 0, void 0, function* () {
            const key = isDevice
                ? this.entryFor.deviceKeypairOfDataOwner(dataOwnerId, publicKeyFingerprint)
                : this.entryFor.cachedRecoveredKeypairOfDataOwner(dataOwnerId, publicKeyFingerprint);
            yield this.keys.storeKeyPair(key, keyPair);
        });
    }
    /**
     * Get an existing key pair for the data owner.
     * @param dataOwnerId id of the data owner with the key.
     * @param publicKeyFingerprint fingerprint of a public key of the data owner.
     * @param legacyPublicKey the legacy public key of the data owner, if present (only used to know if we should search for the key in 'legacy' storage
     * locations.
     * @return the keypair and if the key was generated on this device or undefined if the key pair could not be found.
     */
    loadKey(dataOwnerId, publicKeyFingerprint, legacyPublicKey) {
        return __awaiter(this, void 0, void 0, function* () {
            var _a, _b;
            const deviceKey = (_b = (_a = (yield this.keys.getKeypair(this.entryFor.deviceKeypairOfDataOwner(dataOwnerId, publicKeyFingerprint)))) !== null && _a !== void 0 ? _a : (yield this.keys.getKeypair(`org.taktik.icure.rsa.${dataOwnerId}.${publicKeyFingerprint}`))) !== null && _b !== void 0 ? _b : (!!legacyPublicKey && (0, utils_1.fingerprintV1)(legacyPublicKey) === publicKeyFingerprint
                ? yield this.keys.getKeypair(`org.taktik.icure.rsa.${dataOwnerId}`)
                : undefined);
            if (deviceKey)
                return { pair: deviceKey, isDevice: true };
            const cachedKey = yield this.keys.getKeypair(this.entryFor.cachedRecoveredKeypairOfDataOwner(dataOwnerId, publicKeyFingerprint));
            if (cachedKey)
                return { pair: cachedKey, isDevice: false };
            return undefined;
        });
    }
    /**
     * Save the results of public key verification. If there were already results stored the entries will be merged. In case of conflicts the new
     * {@link verificationDetails} take priority over the stored data.
     * @param dataOwnerId id of a data owner.
     * @param verificationDetails results of verification, associates key fingerprints to true if they were verified by the user or false otherwise.
     * @return the updated keys
     */
    saveSelfVerifiedKeys(dataOwnerId, verificationDetails) {
        return __awaiter(this, void 0, void 0, function* () {
            const updated = Object.assign(Object.assign({}, (yield this.loadSelfVerifiedKeys(dataOwnerId))), verificationDetails);
            yield this.data.setItem(this.entryFor.selfPublicKeysVerificationCacheForDataOwner(dataOwnerId), JSON.stringify(updated));
            return updated;
        });
    }
    /**
     * Get the last saved results of public key verification.
     * @param dataOwnerId id of a data owner.
     * @return saved results of verification, associates key fingerprints to true if they were verified by the user or false otherwise. If no results
     * were saved returns an empty object instead.
     * @throws if the stored results are not in a valid format.
     */
    loadSelfVerifiedKeys(dataOwnerId) {
        return __awaiter(this, void 0, void 0, function* () {
            const dataString = yield this.data.getItem(this.entryFor.selfPublicKeysVerificationCacheForDataOwner(dataOwnerId));
            if (dataString) {
                const parsed = JSON.parse(dataString);
                Object.entries(parsed).forEach(([k, v]) => {
                    if (v !== true && v !== false)
                        throw new Error(`Unexpected entry ${k}:${v}`);
                });
                return parsed;
            }
            else
                return {};
        });
    }
    /**
     * Saves a signature and verification key pair. Overrides previously saved signature keys (but keeps signature verification keys).
     * @param dataOwnerId id of the data owner with the key.
     * @param publicKeyFingerprint fingerprint of the public key of the pair.
     * @param keyPair the key pair to save.
     */
    saveSignatureKeyPair(dataOwnerId, publicKeyFingerprint, keyPair) {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.keys.storeKeyPair(this.entryFor.signatureKeyForDataOwner(dataOwnerId), keyPair);
            yield this.keys.storePublicKey(this.entryFor.signatureVerificationKeyForDataOwner(dataOwnerId, publicKeyFingerprint), keyPair.publicKey);
        });
    }
    /**
     * Loads the signature key for the data owner.
     * @param dataOwnerId id of the data owner with the key.
     * @return the signature key for the data owner or undefined if there is no signature key stored.
     */
    loadSignatureKey(dataOwnerId) {
        return __awaiter(this, void 0, void 0, function* () {
            return yield this.keys.getKeypair(this.entryFor.signatureKeyForDataOwner(dataOwnerId));
        });
    }
    /**
     * Loads the signature verification key for a data owner with the provided fingerprint.
     * @param dataOwnerId id of the data owner with the key.
     * @param publicKeyFingerprint fingerprint of the verification key.
     * @return the requested signature verification key or undefined if the key could not be found.
     */
    loadSignatureVerificationKey(dataOwnerId, publicKeyFingerprint) {
        return __awaiter(this, void 0, void 0, function* () {
            return yield this.keys.getPublicKey(this.entryFor.signatureVerificationKeyForDataOwner(dataOwnerId, publicKeyFingerprint));
        });
    }
}
exports.IcureStorageFacade = IcureStorageFacade;
//# sourceMappingURL=IcureStorageFacade.js.map