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

package org.bouncycastle.asn1.x509;

import java.util.Collections;
import java.util.HashSet;
import java.util.Enumeration;
import org.bouncycastle.asn1.ASN1ParsingException;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Sequence;
import java.io.IOException;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import java.util.Set;
import java.util.Vector;
import java.util.Hashtable;

public class ExtensionsGenerator
{
    private Hashtable extensions;
    private Vector extOrdering;
    private static final Set dupsAllowed;
    
    public ExtensionsGenerator() {
        this.extensions = new Hashtable();
        this.extOrdering = new Vector();
    }
    
    public void reset() {
        this.extensions = new Hashtable();
        this.extOrdering = new Vector();
    }
    
    public void addExtension(final ASN1ObjectIdentifier key, final boolean b, final ASN1Encodable asn1Encodable) throws IOException {
        final Extension extension = this.extensions.get(key);
        if (extension != null) {
            this.implAddExtensionDup(extension, b, asn1Encodable.toASN1Primitive().getEncoded("DER"));
        }
        else {
            this.implAddExtension(new Extension(key, b, new DEROctetString(asn1Encodable)));
        }
    }
    
    public void addExtension(final ASN1ObjectIdentifier key, final boolean b, final byte[] array) {
        final Extension extension = this.extensions.get(key);
        if (extension != null) {
            this.implAddExtensionDup(extension, b, array);
        }
        else {
            this.implAddExtension(new Extension(key, b, array));
        }
    }
    
    public void addExtension(final Extension extension) {
        if (this.hasExtension(extension.getExtnId())) {
            throw new IllegalArgumentException("extension " + extension.getExtnId() + " already added");
        }
        this.implAddExtension(extension);
    }
    
    @Deprecated
    public void addExtension(final Extensions extensions) {
        this.addExtensions(extensions);
    }
    
    public void addExtensions(final Extensions extensions) {
        final ASN1ObjectIdentifier[] extensionOIDs = extensions.getExtensionOIDs();
        for (int i = 0; i != extensionOIDs.length; ++i) {
            final ASN1ObjectIdentifier asn1ObjectIdentifier = extensionOIDs[i];
            final Extension extension = extensions.getExtension(asn1ObjectIdentifier);
            this.addExtension(ASN1ObjectIdentifier.getInstance(asn1ObjectIdentifier), extension.isCritical(), extension.getExtnValue().getOctets());
        }
    }
    
    public void replaceExtension(final ASN1ObjectIdentifier asn1ObjectIdentifier, final boolean b, final ASN1Encodable asn1Encodable) throws IOException {
        this.replaceExtension(new Extension(asn1ObjectIdentifier, b, new DEROctetString(asn1Encodable)));
    }
    
    public void replaceExtension(final ASN1ObjectIdentifier asn1ObjectIdentifier, final boolean b, final byte[] array) {
        this.replaceExtension(new Extension(asn1ObjectIdentifier, b, array));
    }
    
    public void replaceExtension(final Extension value) {
        if (!this.hasExtension(value.getExtnId())) {
            throw new IllegalArgumentException("extension " + value.getExtnId() + " not present");
        }
        this.extensions.put(value.getExtnId(), value);
    }
    
    public void removeExtension(final ASN1ObjectIdentifier key) {
        if (!this.hasExtension(key)) {
            throw new IllegalArgumentException("extension " + key + " not present");
        }
        this.extOrdering.removeElement(key);
        this.extensions.remove(key);
    }
    
    public boolean hasExtension(final ASN1ObjectIdentifier key) {
        return this.extensions.containsKey(key);
    }
    
    public Extension getExtension(final ASN1ObjectIdentifier key) {
        return this.extensions.get(key);
    }
    
    public boolean isEmpty() {
        return this.extOrdering.isEmpty();
    }
    
    public Extensions generate() {
        final Extension[] array = new Extension[this.extOrdering.size()];
        for (int i = 0; i != this.extOrdering.size(); ++i) {
            array[i] = (Extension)this.extensions.get(this.extOrdering.elementAt(i));
        }
        return new Extensions(array);
    }
    
    private void implAddExtension(final Extension value) {
        this.extOrdering.addElement(value.getExtnId());
        this.extensions.put(value.getExtnId(), value);
    }
    
    private void implAddExtensionDup(final Extension extension, final boolean b, final byte[] array) {
        final ASN1ObjectIdentifier extnId = extension.getExtnId();
        if (!ExtensionsGenerator.dupsAllowed.contains(extnId)) {
            throw new IllegalArgumentException("extension " + extnId + " already added");
        }
        final ASN1Sequence instance = ASN1Sequence.getInstance(ASN1OctetString.getInstance(extension.getExtnValue()).getOctets());
        final ASN1Sequence instance2 = ASN1Sequence.getInstance(array);
        final ASN1EncodableVector asn1EncodableVector = new ASN1EncodableVector(instance.size() + instance2.size());
        final Enumeration objects = instance.getObjects();
        while (objects.hasMoreElements()) {
            asn1EncodableVector.add((ASN1Encodable)objects.nextElement());
        }
        final Enumeration objects2 = instance2.getObjects();
        while (objects2.hasMoreElements()) {
            asn1EncodableVector.add((ASN1Encodable)objects2.nextElement());
        }
        try {
            this.extensions.put(extnId, new Extension(extnId, b, new DEROctetString(new DERSequence(asn1EncodableVector))));
        }
        catch (final IOException ex) {
            throw new ASN1ParsingException(ex.getMessage(), ex);
        }
    }
    
    static {
        final HashSet s = new HashSet();
        s.add(Extension.subjectAlternativeName);
        s.add(Extension.issuerAlternativeName);
        s.add(Extension.subjectDirectoryAttributes);
        s.add(Extension.certificateIssuer);
        dupsAllowed = Collections.unmodifiableSet((Set<?>)s);
    }
}
