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

package com.google.crypto.tink.internal;

import com.google.crypto.tink.Parameters;
import java.util.Objects;
import com.google.crypto.tink.proto.OutputPrefixType;
import com.google.crypto.tink.util.Bytes;
import java.security.GeneralSecurityException;
import javax.annotation.Nullable;
import com.google.crypto.tink.SecretKeyAccess;
import com.google.errorprone.annotations.Immutable;
import com.google.crypto.tink.Key;

@Immutable
public final class LegacyProtoKey extends Key
{
    private final ProtoKeySerialization serialization;
    
    private static void throwIfMissingAccess(final ProtoKeySerialization protoKeySerialization, @Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        switch (protoKeySerialization.getKeyMaterialType()) {
            case SYMMETRIC:
            case ASYMMETRIC_PRIVATE: {
                SecretKeyAccess.requireAccess(access);
                break;
            }
        }
    }
    
    private static Bytes computeOutputPrefix(final ProtoKeySerialization serialization) throws GeneralSecurityException {
        if (serialization.getOutputPrefixType().equals(OutputPrefixType.RAW)) {
            return Bytes.copyFrom(new byte[0]);
        }
        if (serialization.getOutputPrefixType().equals(OutputPrefixType.TINK)) {
            return OutputPrefixUtil.getTinkOutputPrefix(serialization.getIdRequirementOrNull());
        }
        if (serialization.getOutputPrefixType().equals(OutputPrefixType.LEGACY) || serialization.getOutputPrefixType().equals(OutputPrefixType.CRUNCHY)) {
            return OutputPrefixUtil.getLegacyOutputPrefix(serialization.getIdRequirementOrNull());
        }
        throw new GeneralSecurityException("Unknown output prefix type");
    }
    
    public LegacyProtoKey(final ProtoKeySerialization serialization, @Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        throwIfMissingAccess(serialization, access);
        this.serialization = serialization;
    }
    
    @Override
    public boolean equalsKey(final Key key) {
        if (!(key instanceof LegacyProtoKey)) {
            return false;
        }
        final ProtoKeySerialization other = ((LegacyProtoKey)key).serialization;
        return other.getOutputPrefixType().equals(this.serialization.getOutputPrefixType()) && other.getKeyMaterialType().equals(this.serialization.getKeyMaterialType()) && other.getTypeUrl().equals(this.serialization.getTypeUrl()) && Objects.equals(other.getIdRequirementOrNull(), this.serialization.getIdRequirementOrNull()) && com.google.crypto.tink.subtle.Bytes.equal(this.serialization.getValue().toByteArray(), other.getValue().toByteArray());
    }
    
    @Nullable
    @Override
    public Integer getIdRequirementOrNull() {
        return this.serialization.getIdRequirementOrNull();
    }
    
    public ProtoKeySerialization getSerialization(@Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        throwIfMissingAccess(this.serialization, access);
        return this.serialization;
    }
    
    @Override
    public Parameters getParameters() {
        return new LegacyProtoParametersNotForCreation(this.serialization.getTypeUrl(), this.serialization.getOutputPrefixType());
    }
    
    public Bytes getOutputPrefix() throws GeneralSecurityException {
        return computeOutputPrefix(this.serialization);
    }
    
    @Immutable
    private static class LegacyProtoParametersNotForCreation extends Parameters
    {
        private final String typeUrl;
        private final OutputPrefixType outputPrefixType;
        
        @Override
        public boolean hasIdRequirement() {
            return this.outputPrefixType != OutputPrefixType.RAW;
        }
        
        private static String outputPrefixToString(final OutputPrefixType outputPrefixType) {
            switch (outputPrefixType) {
                case TINK: {
                    return "TINK";
                }
                case LEGACY: {
                    return "LEGACY";
                }
                case RAW: {
                    return "RAW";
                }
                case CRUNCHY: {
                    return "CRUNCHY";
                }
                default: {
                    return "UNKNOWN";
                }
            }
        }
        
        @Override
        public String toString() {
            return String.format("(typeUrl=%s, outputPrefixType=%s)", this.typeUrl, outputPrefixToString(this.outputPrefixType));
        }
        
        private LegacyProtoParametersNotForCreation(final String typeUrl, final OutputPrefixType outputPrefixType) {
            this.typeUrl = typeUrl;
            this.outputPrefixType = outputPrefixType;
        }
    }
}
