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

package com.google.crypto.tink.jwt;

import java.util.Iterator;
import com.google.errorprone.annotations.Immutable;
import com.google.crypto.tink.internal.MutablePrimitiveRegistry;
import com.google.crypto.tink.internal.MonitoringClient;
import java.util.List;
import com.google.crypto.tink.internal.MonitoringUtil;
import com.google.crypto.tink.internal.MutableMonitoringRegistry;
import com.google.crypto.tink.KeyStatus;
import java.util.ArrayList;
import com.google.crypto.tink.internal.MonitoringAnnotations;
import java.security.GeneralSecurityException;
import com.google.crypto.tink.internal.KeysetHandleInterface;
import com.google.crypto.tink.internal.PrimitiveWrapper;

class JwtMacWrapper implements PrimitiveWrapper<JwtMac, JwtMac>
{
    private static final JwtMacWrapper WRAPPER;
    
    private static void validate(final KeysetHandleInterface keysetHandle) throws GeneralSecurityException {
        if (keysetHandle.getPrimary() == null) {
            throw new GeneralSecurityException("Primitive set has no primary.");
        }
    }
    
    @Override
    public JwtMac wrap(final KeysetHandleInterface keysetHandle, final MonitoringAnnotations annotations, final PrimitiveFactory<JwtMac> factory) throws GeneralSecurityException {
        validate(keysetHandle);
        final List<JwtMacWithId> allMacs = new ArrayList<JwtMacWithId>(keysetHandle.size());
        for (int i = 0; i < keysetHandle.size(); ++i) {
            final KeysetHandleInterface.Entry entry = keysetHandle.getAt(i);
            if (entry.getStatus().equals(KeyStatus.ENABLED)) {
                final JwtMac jwtMac = factory.create(entry);
                allMacs.add(new JwtMacWithId(jwtMac, entry.getId()));
            }
        }
        MonitoringClient.Logger computeLogger;
        MonitoringClient.Logger verifyLogger;
        if (!annotations.isEmpty()) {
            final MonitoringClient client = MutableMonitoringRegistry.globalInstance().getMonitoringClient();
            computeLogger = client.createLogger(keysetHandle, annotations, "jwtmac", "compute");
            verifyLogger = client.createLogger(keysetHandle, annotations, "jwtmac", "verify");
        }
        else {
            computeLogger = MonitoringUtil.DO_NOTHING_LOGGER;
            verifyLogger = MonitoringUtil.DO_NOTHING_LOGGER;
        }
        final JwtMac primaryMac = factory.create(keysetHandle.getPrimary());
        return new WrappedJwtMac(new JwtMacWithId(primaryMac, keysetHandle.getPrimary().getId()), (List)allMacs, computeLogger, verifyLogger);
    }
    
    @Override
    public Class<JwtMac> getPrimitiveClass() {
        return JwtMac.class;
    }
    
    @Override
    public Class<JwtMac> getInputPrimitiveClass() {
        return JwtMac.class;
    }
    
    public static void register() throws GeneralSecurityException {
        MutablePrimitiveRegistry.globalInstance().registerPrimitiveWrapper((PrimitiveWrapper<Object, Object>)JwtMacWrapper.WRAPPER);
    }
    
    static {
        WRAPPER = new JwtMacWrapper();
    }
    
    private static class JwtMacWithId
    {
        final JwtMac jwtMac;
        final int id;
        
        JwtMacWithId(final JwtMac jwtMac, final int id) {
            this.jwtMac = jwtMac;
            this.id = id;
        }
    }
    
    @Immutable
    private static class WrappedJwtMac implements JwtMac
    {
        private final JwtMacWithId primary;
        private final List<JwtMacWithId> allMacs;
        private final MonitoringClient.Logger computeLogger;
        private final MonitoringClient.Logger verifyLogger;
        
        private WrappedJwtMac(final JwtMacWithId primary, final List<JwtMacWithId> allMacs, final MonitoringClient.Logger computeLogger, final MonitoringClient.Logger verifyLogger) {
            this.primary = primary;
            this.allMacs = allMacs;
            this.computeLogger = computeLogger;
            this.verifyLogger = verifyLogger;
        }
        
        @Override
        public String computeMacAndEncode(final RawJwt token) throws GeneralSecurityException {
            try {
                final String result = this.primary.jwtMac.computeMacAndEncode(token);
                this.computeLogger.log(this.primary.id, 1L);
                return result;
            }
            catch (final GeneralSecurityException e) {
                this.computeLogger.logFailure();
                throw e;
            }
        }
        
        @Override
        public VerifiedJwt verifyMacAndDecode(final String compact, final JwtValidator validator) throws GeneralSecurityException {
            GeneralSecurityException interestingException = null;
            for (final JwtMacWithId macAndId : this.allMacs) {
                try {
                    final VerifiedJwt result = macAndId.jwtMac.verifyMacAndDecode(compact, validator);
                    this.verifyLogger.log(macAndId.id, 1L);
                    return result;
                }
                catch (final GeneralSecurityException e) {
                    if (!(e instanceof JwtInvalidException)) {
                        continue;
                    }
                    interestingException = e;
                    continue;
                }
                break;
            }
            this.verifyLogger.logFailure();
            if (interestingException != null) {
                throw interestingException;
            }
            throw new GeneralSecurityException("invalid MAC");
        }
    }
}
