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

package com.nimbusds.jose.jwk.source;

import java.util.Objects;
import com.nimbusds.jose.KeySourceException;
import com.nimbusds.jose.util.cache.CachedObject;
import com.nimbusds.jose.util.events.Event;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.util.events.EventListener;
import com.nimbusds.jose.shaded.jcip.ThreadSafe;
import com.nimbusds.jose.proc.SecurityContext;

@ThreadSafe
public class OutageTolerantJWKSetSource<C extends SecurityContext> extends AbstractCachingJWKSetSource<C>
{
    private final EventListener<OutageTolerantJWKSetSource<C>, C> eventListener;
    
    public OutageTolerantJWKSetSource(final JWKSetSource<C> source, final long timeToLive, final EventListener<OutageTolerantJWKSetSource<C>, C> eventListener) {
        super(source, timeToLive);
        this.eventListener = eventListener;
    }
    
    @Override
    public JWKSet getJWKSet(final JWKSetCacheRefreshEvaluator refreshEvaluator, final long currentTime, final C context) throws KeySourceException {
        try {
            final JWKSet jwkSet = this.getSource().getJWKSet(refreshEvaluator, currentTime, context);
            this.cacheJWKSet(jwkSet, currentTime);
            return jwkSet;
        }
        catch (final JWKSetUnavailableException e) {
            final CachedObject<JWKSet> cache = this.getCachedJWKSet();
            if (cache != null && cache.isValid(currentTime)) {
                final long remainingTime = cache.getExpirationTime() - currentTime;
                if (this.eventListener != null) {
                    this.eventListener.notify((Event<OutageTolerantJWKSetSource<C>, C>)new OutageEvent(this, (Exception)e, remainingTime, (SecurityContext)context));
                }
                final JWKSet jwkSet2 = cache.get();
                final JWKSet jwkSetClone = new JWKSet(jwkSet2.getKeys());
                if (!refreshEvaluator.requiresRefresh(jwkSetClone)) {
                    return jwkSetClone;
                }
            }
            throw e;
        }
    }
    
    public static class OutageEvent<C extends SecurityContext> extends AbstractJWKSetSourceEvent<OutageTolerantJWKSetSource<C>, C>
    {
        private final Exception exception;
        private final long remainingTime;
        
        private OutageEvent(final OutageTolerantJWKSetSource<C> source, final Exception exception, final long remainingTime, final C context) {
            super(source, context);
            Objects.requireNonNull(exception);
            this.exception = exception;
            this.remainingTime = remainingTime;
        }
        
        public Exception getException() {
            return this.exception;
        }
        
        public long getRemainingTime() {
            return this.remainingTime;
        }
    }
}
