// 
// Decompiled by Procyon v0.6.0
// 

package com.google.crypto.tink.internal;

import com.google.crypto.tink.AccessesPartialKey;
import com.google.errorprone.annotations.RestrictedApi;
import com.google.crypto.tink.Key;
import com.google.crypto.tink.SecretKeyAccess;
import javax.annotation.Nullable;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.util.HashMap;
import com.google.crypto.tink.Parameters;
import java.util.Map;

public final class MutableKeyDerivationRegistry
{
    private final Map<Class<? extends Parameters>, InsecureKeyCreator<? extends Parameters>> creators;
    private static final MutableKeyDerivationRegistry globalInstance;
    
    public MutableKeyDerivationRegistry() {
        this.creators = new HashMap<Class<? extends Parameters>, InsecureKeyCreator<? extends Parameters>>();
    }
    
    public static MutableKeyDerivationRegistry globalInstance() {
        return MutableKeyDerivationRegistry.globalInstance;
    }
    
    public synchronized <ParametersT extends Parameters> void add(final InsecureKeyCreator<ParametersT> creator, final Class<ParametersT> parametersClass) throws GeneralSecurityException {
        final InsecureKeyCreator<?> existingCreator = this.creators.get(parametersClass);
        if (existingCreator != null && !existingCreator.equals(creator)) {
            throw new GeneralSecurityException("Different key creator for parameters class already inserted");
        }
        this.creators.put(parametersClass, creator);
    }
    
    @RestrictedApi(explanation = "Accessing parts of keys can produce unexpected incompatibilities, annotate the function with @AccessesPartialKey", link = "https://developers.google.com/tink/design/access_control#accessing_partial_keys", allowedOnPath = ".*Test\\.java", allowlistAnnotations = { AccessesPartialKey.class })
    public Key createKeyFromRandomness(final Parameters parameters, final InputStream inputStream, @Nullable final Integer idRequirement, final SecretKeyAccess access) throws GeneralSecurityException {
        return this.createKeyFromRandomnessTyped(parameters, inputStream, idRequirement, access);
    }
    
    private synchronized <ParametersT extends Parameters> Key createKeyFromRandomnessTyped(final ParametersT parameters, final InputStream inputStream, @Nullable final Integer idRequirement, final SecretKeyAccess access) throws GeneralSecurityException {
        final Class<?> parametersClass = parameters.getClass();
        final InsecureKeyCreator<?> creator = this.creators.get(parametersClass);
        if (creator == null) {
            throw new GeneralSecurityException("Cannot use key derivation to derive key for parameters " + parameters + ": no key creator for this class was registered.");
        }
        final InsecureKeyCreator<ParametersT> castCreator = (InsecureKeyCreator<ParametersT>)creator;
        return castCreator.createKeyFromRandomness(parameters, inputStream, idRequirement, access);
    }
    
    static {
        globalInstance = new MutableKeyDerivationRegistry();
    }
    
    public interface InsecureKeyCreator<ParametersT extends Parameters>
    {
        Key createKeyFromRandomness(final ParametersT parameters, final InputStream inputStream, @Nullable final Integer idRequirement, final SecretKeyAccess access) throws GeneralSecurityException;
    }
}
