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

package com.google.crypto.tink.internal;

import javax.annotation.Nullable;
import com.google.crypto.tink.SecretKeyAccess;
import com.google.crypto.tink.Parameters;
import java.security.GeneralSecurityException;
import com.google.crypto.tink.Key;
import java.util.concurrent.atomic.AtomicReference;

public final class MutableSerializationRegistry
{
    private static final MutableSerializationRegistry GLOBAL_INSTANCE;
    private final AtomicReference<SerializationRegistry> registry;
    
    private static MutableSerializationRegistry createGlobalInstance() throws GeneralSecurityException {
        final MutableSerializationRegistry registry = new MutableSerializationRegistry();
        registry.registerKeySerializer((KeySerializer<Key, Serialization>)KeySerializer.create((KeySerializer.KeySerializationFunction<KeyT, SerializationT>)LegacyProtoKey::getSerialization, (Class<KeyT>)LegacyProtoKey.class, (Class<SerializationT>)ProtoKeySerialization.class));
        return registry;
    }
    
    public static MutableSerializationRegistry globalInstance() {
        return MutableSerializationRegistry.GLOBAL_INSTANCE;
    }
    
    public MutableSerializationRegistry() {
        this.registry = new AtomicReference<SerializationRegistry>(new SerializationRegistry.Builder().build());
    }
    
    public synchronized <KeyT extends Key, SerializationT extends Serialization> void registerKeySerializer(final KeySerializer<KeyT, SerializationT> serializer) throws GeneralSecurityException {
        final SerializationRegistry newRegistry = new SerializationRegistry.Builder(this.registry.get()).registerKeySerializer(serializer).build();
        this.registry.set(newRegistry);
    }
    
    public synchronized <SerializationT extends Serialization> void registerKeyParser(final KeyParser<SerializationT> parser) throws GeneralSecurityException {
        final SerializationRegistry newRegistry = new SerializationRegistry.Builder(this.registry.get()).registerKeyParser(parser).build();
        this.registry.set(newRegistry);
    }
    
    public synchronized <ParametersT extends Parameters, SerializationT extends Serialization> void registerParametersSerializer(final ParametersSerializer<ParametersT, SerializationT> serializer) throws GeneralSecurityException {
        final SerializationRegistry newRegistry = new SerializationRegistry.Builder(this.registry.get()).registerParametersSerializer(serializer).build();
        this.registry.set(newRegistry);
    }
    
    public synchronized <SerializationT extends Serialization> void registerParametersParser(final ParametersParser<SerializationT> parser) throws GeneralSecurityException {
        final SerializationRegistry newRegistry = new SerializationRegistry.Builder(this.registry.get()).registerParametersParser(parser).build();
        this.registry.set(newRegistry);
    }
    
    public <SerializationT extends Serialization> boolean hasParserForKey(final SerializationT serializedKey) {
        return this.registry.get().hasParserForKey(serializedKey);
    }
    
    public <SerializationT extends Serialization> Key parseKey(final SerializationT serializedKey, @Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        return this.registry.get().parseKey(serializedKey, access);
    }
    
    public Key parseKeyWithLegacyFallback(final ProtoKeySerialization protoKeySerialization, @Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        if (!this.hasParserForKey(protoKeySerialization)) {
            return new LegacyProtoKey(protoKeySerialization, access);
        }
        return this.parseKey(protoKeySerialization, access);
    }
    
    public <KeyT extends Key, SerializationT extends Serialization> boolean hasSerializerForKey(final KeyT key, final Class<SerializationT> serializationClass) {
        return this.registry.get().hasSerializerForKey(key, serializationClass);
    }
    
    public <KeyT extends Key, SerializationT extends Serialization> SerializationT serializeKey(final KeyT key, final Class<SerializationT> serializationClass, @Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        return this.registry.get().serializeKey(key, serializationClass, access);
    }
    
    public <SerializationT extends Serialization> boolean hasParserForParameters(final SerializationT serializedParameters) {
        return this.registry.get().hasParserForParameters(serializedParameters);
    }
    
    public <SerializationT extends Serialization> Parameters parseParameters(final SerializationT serializedParameters) throws GeneralSecurityException {
        return this.registry.get().parseParameters(serializedParameters);
    }
    
    public Parameters parseParametersWithLegacyFallback(final ProtoParametersSerialization protoParametersSerialization) throws GeneralSecurityException {
        if (!this.hasParserForParameters(protoParametersSerialization)) {
            return new LegacyProtoParameters(protoParametersSerialization);
        }
        return this.parseParameters(protoParametersSerialization);
    }
    
    public <ParametersT extends Parameters, SerializationT extends Serialization> boolean hasSerializerForParameters(final ParametersT parameters, final Class<SerializationT> serializationClass) {
        return this.registry.get().hasSerializerForParameters(parameters, serializationClass);
    }
    
    public <ParametersT extends Parameters, SerializationT extends Serialization> SerializationT serializeParameters(final ParametersT parameters, final Class<SerializationT> serializationClass) throws GeneralSecurityException {
        return this.registry.get().serializeParameters(parameters, serializationClass);
    }
    
    static {
        GLOBAL_INSTANCE = TinkBugException.exceptionIsBug(MutableSerializationRegistry::createGlobalInstance);
    }
}
