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

package org.bouncycastle.jce.provider;

import java.util.ArrayList;
import org.bouncycastle.util.Iterable;
import java.util.Collections;
import java.util.WeakHashMap;
import java.net.URLConnection;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import javax.naming.NamingException;
import javax.naming.directory.InitialDirContext;
import java.util.Hashtable;
import java.security.cert.CRLException;
import java.io.IOException;
import java.util.Iterator;
import org.bouncycastle.util.Store;
import java.util.Collection;
import java.security.cert.CRL;
import org.bouncycastle.util.CollectionStore;
import java.security.cert.X509CRL;
import org.bouncycastle.util.Selector;
import java.util.Date;
import java.security.cert.CertificateFactory;
import org.bouncycastle.jcajce.PKIXCRLStore;
import java.lang.ref.WeakReference;
import java.net.URI;
import java.util.Map;

class CrlCache
{
    private static final int DEFAULT_TIMEOUT = 15000;
    private static Map<URI, WeakReference<PKIXCRLStore>> cache;
    
    static synchronized PKIXCRLStore getCrl(final CertificateFactory certificateFactory, final Date when, final URI uri) throws IOException, CRLException {
        PKIXCRLStore pkixcrlStore = null;
        final WeakReference weakReference = CrlCache.cache.get(uri);
        if (weakReference != null) {
            pkixcrlStore = (PKIXCRLStore)weakReference.get();
        }
        if (pkixcrlStore != null) {
            boolean b = false;
            final Iterator iterator = pkixcrlStore.getMatches(null).iterator();
            while (iterator.hasNext()) {
                final Date nextUpdate = ((X509CRL)iterator.next()).getNextUpdate();
                if (nextUpdate != null && nextUpdate.before(when)) {
                    b = true;
                    break;
                }
            }
            if (!b) {
                return pkixcrlStore;
            }
        }
        Collection collection;
        if (uri.getScheme().equals("ldap")) {
            collection = getCrlsFromLDAP(certificateFactory, uri);
        }
        else {
            collection = getCrls(certificateFactory, uri);
        }
        final LocalCRLStore referent = new LocalCRLStore(new CollectionStore<CRL>(collection));
        CrlCache.cache.put(uri, new WeakReference<PKIXCRLStore>(referent));
        return referent;
    }
    
    private static Collection getCrlsFromLDAP(final CertificateFactory certificateFactory, final URI obj) throws IOException, CRLException {
        final Hashtable hashtable = new Hashtable();
        hashtable.put("java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory");
        hashtable.put("java.naming.provider.url", obj.toString());
        byte[] buf;
        try {
            buf = (byte[])new InitialDirContext(hashtable).getAttributes("").get("certificateRevocationList;binary").get();
        }
        catch (final NamingException cause) {
            throw new CRLException("issue connecting to: " + obj.toString(), cause);
        }
        if (buf == null || buf.length == 0) {
            throw new CRLException("no CRL returned from: " + obj);
        }
        return certificateFactory.generateCRLs(new ByteArrayInputStream(buf));
    }
    
    private static Collection getCrls(final CertificateFactory certificateFactory, final URI uri) throws IOException, CRLException {
        final URLConnection openConnection = uri.toURL().openConnection();
        openConnection.setConnectTimeout(15000);
        openConnection.setReadTimeout(15000);
        final InputStream inputStream = openConnection.getInputStream();
        final Collection<? extends CRL> generateCRLs = certificateFactory.generateCRLs(inputStream);
        inputStream.close();
        return generateCRLs;
    }
    
    static {
        CrlCache.cache = Collections.synchronizedMap(new WeakHashMap<URI, WeakReference<PKIXCRLStore>>());
    }
    
    private static class LocalCRLStore<T extends CRL> implements PKIXCRLStore, Iterable<CRL>
    {
        private Collection<CRL> _local;
        
        public LocalCRLStore(final Store<CRL> store) {
            this._local = new ArrayList<CRL>(store.getMatches(null));
        }
        
        @Override
        public Collection getMatches(final Selector selector) {
            if (selector == null) {
                return new ArrayList(this._local);
            }
            final ArrayList list = new ArrayList();
            for (final CRL crl : this._local) {
                if (selector.match(crl)) {
                    list.add(crl);
                }
            }
            return list;
        }
        
        @Override
        public Iterator<CRL> iterator() {
            return this.getMatches(null).iterator();
        }
    }
}
