// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { NodeEncryptionMaterial, NodeDecryptionMaterial, WebCryptoEncryptionMaterial, WebCryptoDecryptionMaterial, isEncryptionMaterial, isDecryptionMaterial, } from './cryptographic_material';
import { NodeAlgorithmSuite } from './node_algorithms';
import { needs } from './needs';
export function cloneMaterial(source) {
    const { suite, encryptionContext } = source;
    const clone = (suite instanceof NodeAlgorithmSuite
        ? source instanceof NodeEncryptionMaterial
            ? new NodeEncryptionMaterial(suite, encryptionContext)
            : new NodeDecryptionMaterial(suite, encryptionContext)
        : source instanceof WebCryptoEncryptionMaterial
            ? new WebCryptoEncryptionMaterial(suite, encryptionContext)
            : new WebCryptoDecryptionMaterial(suite, encryptionContext));
    /* The setTrace _must_ be the first trace,
     * If the material is an EncryptionMaterial
     * then the data key *must* have been generated.
     * If the material is DecryptionMaterial
     * then the data key *must* have been decrypted.
     * i.e. the required flags are:
     * WRAPPING_KEY_GENERATED_DATA_KEY, WRAPPING_KEY_DECRYPTED_DATA_KEY
     * These are controlled by the material itself.
     * Furthermore, subsequent trace entries,
     * *must* be in the same order as the added encrypted data keys.
     * See cryptographic_materials.ts `decorateCryptographicMaterial`, `decorateWebCryptoMaterial`.
     */
    const [setTrace, ...traces] = source.keyringTrace.slice();
    if (source.hasUnencryptedDataKey) {
        const udk = cloneUnencryptedDataKey(source.getUnencryptedDataKey());
        clone.setUnencryptedDataKey(udk, setTrace);
    }
    if (source.hasCryptoKey) {
        const cryptoKey = source.getCryptoKey();
        clone.setCryptoKey(cryptoKey, setTrace);
    }
    if (isEncryptionMaterial(source) && isEncryptionMaterial(clone)) {
        const encryptedDataKeys = source.encryptedDataKeys;
        /* Precondition: For each encrypted data key, there must be a trace. */
        needs(encryptedDataKeys.length === traces.length, 'KeyringTrace length does not match encrypted data keys.');
        encryptedDataKeys.forEach((edk, i) => {
            const { providerInfo, providerId } = edk;
            const { keyNamespace, keyName, flags } = traces[i];
            /* Precondition: The traces must be in the same order as the encrypted data keys. */
            needs(keyName === providerInfo && keyNamespace === providerId, 'Keyring trace does not match encrypted data key.');
            clone.addEncryptedDataKey(edk, flags);
        });
        if (source.suite.signatureCurve && source.signatureKey) {
            clone.setSignatureKey(source.signatureKey);
        }
    }
    else if (isDecryptionMaterial(source) && isDecryptionMaterial(clone)) {
        /* Precondition: On Decrypt there must not be any additional traces other than the setTrace. */
        needs(!traces.length, 'Only 1 trace is valid on DecryptionMaterials.');
        if (source.suite.signatureCurve && source.verificationKey) {
            clone.setVerificationKey(source.verificationKey);
        }
    }
    else {
        throw new Error('Material mismatch');
    }
    return clone;
}
function cloneUnencryptedDataKey(dataKey) {
    if (dataKey instanceof Uint8Array) {
        return new Uint8Array(dataKey);
    }
    return dataKey;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvbmVfY3J5cHRvZ3JhcGhpY19tYXRlcmlhbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbG9uZV9jcnlwdG9ncmFwaGljX21hdGVyaWFsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLG9FQUFvRTtBQUNwRSxzQ0FBc0M7QUFFdEMsT0FBTyxFQUNMLHNCQUFzQixFQUN0QixzQkFBc0IsRUFDdEIsMkJBQTJCLEVBQzNCLDJCQUEyQixFQUMzQixvQkFBb0IsRUFDcEIsb0JBQW9CLEdBQ3JCLE1BQU0sMEJBQTBCLENBQUE7QUFDakMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFFdEQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFNBQVMsQ0FBQTtBQVEvQixNQUFNLFVBQVUsYUFBYSxDQUFxQixNQUFTO0lBQ3pELE1BQU0sRUFBRSxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsR0FBRyxNQUFNLENBQUE7SUFFM0MsTUFBTSxLQUFLLEdBQUcsQ0FDWixLQUFLLFlBQVksa0JBQWtCO1FBQ2pDLENBQUMsQ0FBQyxNQUFNLFlBQVksc0JBQXNCO1lBQ3hDLENBQUMsQ0FBQyxJQUFJLHNCQUFzQixDQUFDLEtBQUssRUFBRSxpQkFBaUIsQ0FBQztZQUN0RCxDQUFDLENBQUMsSUFBSSxzQkFBc0IsQ0FBQyxLQUFLLEVBQUUsaUJBQWlCLENBQUM7UUFDeEQsQ0FBQyxDQUFDLE1BQU0sWUFBWSwyQkFBMkI7WUFDL0MsQ0FBQyxDQUFDLElBQUksMkJBQTJCLENBQUMsS0FBSyxFQUFFLGlCQUFpQixDQUFDO1lBQzNELENBQUMsQ0FBQyxJQUFJLDJCQUEyQixDQUFDLEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxDQUN6RCxDQUFBO0lBRU47Ozs7Ozs7Ozs7O09BV0c7SUFDSCxNQUFNLENBQUMsUUFBUSxFQUFFLEdBQUcsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQTtJQUV6RCxJQUFJLE1BQU0sQ0FBQyxxQkFBcUIsRUFBRTtRQUNoQyxNQUFNLEdBQUcsR0FBRyx1QkFBdUIsQ0FBQyxNQUFNLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxDQUFBO1FBQ25FLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUE7S0FDM0M7SUFFRCxJQUFLLE1BQXNDLENBQUMsWUFBWSxFQUFFO1FBQ3hELE1BQU0sU0FBUyxHQUFJLE1BQXNDLENBQUMsWUFBWSxFQUFFLENBQ3ZFO1FBQUMsS0FBcUMsQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFBO0tBQzFFO0lBRUQsSUFBSSxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsRUFBRTtRQUMvRCxNQUFNLGlCQUFpQixHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQTtRQUNsRCx1RUFBdUU7UUFDdkUsS0FBSyxDQUNILGlCQUFpQixDQUFDLE1BQU0sS0FBSyxNQUFNLENBQUMsTUFBTSxFQUMxQyx5REFBeUQsQ0FDMUQsQ0FBQTtRQUNELGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNuQyxNQUFNLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxHQUFHLEdBQUcsQ0FBQTtZQUN4QyxNQUFNLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUE7WUFDbEQsb0ZBQW9GO1lBQ3BGLEtBQUssQ0FDSCxPQUFPLEtBQUssWUFBWSxJQUFJLFlBQVksS0FBSyxVQUFVLEVBQ3ZELGtEQUFrRCxDQUNuRCxDQUFBO1lBQ0QsS0FBSyxDQUFDLG1CQUFtQixDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQTtRQUN2QyxDQUFDLENBQUMsQ0FBQTtRQUVGLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLElBQUksTUFBTSxDQUFDLFlBQVksRUFBRTtZQUN0RCxLQUFLLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQTtTQUMzQztLQUNGO1NBQU0sSUFBSSxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsRUFBRTtRQUN0RSwrRkFBK0Y7UUFDL0YsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSwrQ0FBK0MsQ0FBQyxDQUFBO1FBQ3RFLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLElBQUksTUFBTSxDQUFDLGVBQWUsRUFBRTtZQUN6RCxLQUFLLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFBO1NBQ2pEO0tBQ0Y7U0FBTTtRQUNMLE1BQU0sSUFBSSxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQTtLQUNyQztJQUVELE9BQU8sS0FBSyxDQUFBO0FBQ2QsQ0FBQztBQUVELFNBQVMsdUJBQXVCLENBQUMsT0FBc0M7SUFDckUsSUFBSSxPQUFPLFlBQVksVUFBVSxFQUFFO1FBQ2pDLE9BQU8sSUFBSSxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUE7S0FDL0I7SUFDRCxPQUFPLE9BQU8sQ0FBQTtBQUNoQixDQUFDIn0=