package org.bouncycastle.x509;

import org.bouncycastle.util.Selector;
import org.bouncycastle.util.Store;

import java.security.InvalidAlgorithmParameterException;
import java.security.cert.CertSelector;
import java.security.cert.CertStore;
import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509CertSelector;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * This class extends the PKIXParameters with a validity model parameter.
 *
 * @deprecated use PKIXExtendedParameters
 */
public class ExtendedPKIXParameters
    extends PKIXParameters
{

    private List stores;

    private Selector selector;

    private boolean additionalLocationsEnabled;

    private List additionalStores;

    private Set trustedACIssuers;

    private Set necessaryACAttributes;

    private Set prohibitedACAttributes;

    private Set attrCertCheckers;

    /**
     * Creates an instance of <code>PKIXParameters</code> with the specified
     * <code>Set</code> of most-trusted CAs. Each element of the set is a
     * {@link TrustAnchor TrustAnchor}.
     * <p>
     *     Note that the <code>Set</code>
     * is copied to protect against subsequent modifications.
     * </p>
     * 
     * @param trustAnchors a <code>Set</code> of <code>TrustAnchor</code>s
     * @throws InvalidAlgorithmParameterException if the specified
     *             <code>Set</code> is empty.
     * @throws NullPointerException if the specified <code>Set</code> is
     *             <code>null</code>
     * @throws ClassCastException if any of the elements in the <code>Set</code>
     *             is not of type <code>java.security.cert.TrustAnchor</code>
     */
    public ExtendedPKIXParameters(Set trustAnchors)
        throws InvalidAlgorithmParameterException
    {
        super(trustAnchors);
        stores = new ArrayList();
        additionalStores = new ArrayList();
        trustedACIssuers = new HashSet();
        necessaryACAttributes = new HashSet();
        prohibitedACAttributes = new HashSet();
        attrCertCheckers = new HashSet();
    }

    /**
     * Returns an instance with the parameters of a given
     * <code>PKIXParameters</code> object.
     * 
     * @param pkixParams The given <code>PKIXParameters</code>
     * @return an extended PKIX params object
     */
    public static ExtendedPKIXParameters getInstance(PKIXParameters pkixParams)
    {
        ExtendedPKIXParameters params;
        try
        {
            params = new ExtendedPKIXParameters(pkixParams.getTrustAnchors());
        }
        catch (Exception e)
        {
            // cannot happen
            throw new RuntimeException(e.getMessage());
        }
        params.setParams(pkixParams);
        return params;
    }

    /**
     * Method to support <code>clone()</code> under J2ME.
     * <code>super.clone()</code> does not exist and fields are not copied.
     * 
     * @param params Parameters to set. If this are
     *            <code>ExtendedPKIXParameters</code> they are copied to.
     */
    protected void setParams(PKIXParameters params)
    {
        setDate(params.getDate());
        setCertPathCheckers(params.getCertPathCheckers());
        setCertStores(params.getCertStores());
        setAnyPolicyInhibited(params.isAnyPolicyInhibited());
        setExplicitPolicyRequired(params.isExplicitPolicyRequired());
        setPolicyMappingInhibited(params.isPolicyMappingInhibited());
        setRevocationEnabled(params.isRevocationEnabled());
        setInitialPolicies(params.getInitialPolicies());
        setPolicyQualifiersRejected(params.getPolicyQualifiersRejected());
        setSigProvider(params.getSigProvider());
        setTargetCertConstraints(params.getTargetCertConstraints());
        try
        {
            setTrustAnchors(params.getTrustAnchors());
        }
        catch (Exception e)
        {
            // cannot happen
            throw new RuntimeException(e.getMessage());
        }
        if (params instanceof ExtendedPKIXParameters)
        {
            ExtendedPKIXParameters _params = (ExtendedPKIXParameters) params;
            validityModel = _params.validityModel;
            useDeltas = _params.useDeltas;
            additionalLocationsEnabled = _params.additionalLocationsEnabled;
            selector = _params.selector == null ? null
                : (Selector) _params.selector.clone();
            stores = new ArrayList(_params.stores);
            additionalStores = new ArrayList(_params.additionalStores);
            trustedACIssuers = new HashSet(_params.trustedACIssuers);
            prohibitedACAttributes = new HashSet(_params.prohibitedACAttributes);
            necessaryACAttributes = new HashSet(_params.necessaryACAttributes);
            attrCertCheckers = new HashSet(_params.attrCertCheckers);
        }
    }

    /**
     * This is the default PKIX validity model. Actually there are two variants
     * of this: The PKIX model and the modified PKIX model. The PKIX model
     * verifies that all involved certificates must have been valid at the
     * current time. The modified PKIX model verifies that all involved
     * certificates were valid at the signing time. Both are indirectly choosen
     * with the {@link PKIXParameters#setDate(java.util.Date)} method, so this
     * methods sets the Date when <em>all</em> certificates must have been
     * valid.
     */
    public static final int PKIX_VALIDITY_MODEL = 0;

    /**
     * This model uses the following validity model. Each certificate must have
     * been valid at the moment where is was used. That means the end
     * certificate must have been valid at the time the signature was done. The
     * CA certificate which signed the end certificate must have been valid,
     * when the end certificate was signed. The CA (or Root CA) certificate must
     * have been valid, when the CA certificate was signed and so on. So the
     * {@link PKIXParameters#setDate(java.util.Date)} method sets the time, when
     * the <em>end certificate</em> must have been valid.
     * <p>
     * It is used e.g.
     * in the German signature law.
     * </p>
     */
    public static final int CHAIN_VALIDITY_MODEL = 1;

    private int validityModel = PKIX_VALIDITY_MODEL;

    private boolean useDeltas = false;

    /**
     * Defaults to <code>false</code>.
     * 
     * @return Returns if delta CRLs should be used.
     */
    public boolean isUseDeltasEnabled()
    {
        return useDeltas;
    }

    /**
     * Sets if delta CRLs should be used for checking the revocation status.
     * 
     * @param useDeltas <code>true</code> if delta CRLs should be used.
     */
    public void setUseDeltasEnabled(boolean useDeltas)
    {
        this.useDeltas = useDeltas;
    }

    /**
     * @return Returns the validity model.
     * @see #CHAIN_VALIDITY_MODEL
     * @see #PKIX_VALIDITY_MODEL
     */
    public int getValidityModel()
    {
        return validityModel;
    }

    /**
     * Sets the Java CertStore to this extended PKIX parameters.
     * 
     * @throws ClassCastException if an element of <code>stores</code> is not
     *             a <code>CertStore</code>.
     */
    public void setCertStores(List stores)
    {
        if (stores != null)
        {
            Iterator it = stores.iterator();
            while (it.hasNext())
            {
                addCertStore((CertStore)it.next());
            }
        }
    }

    /**
     * Sets the Bouncy Castle Stores for finding CRLs, certificates, attribute
     * certificates or cross certificates.
     * <p>
     * The <code>List</code> is cloned.
     * 
     * @param stores A list of stores to use.
     * @see #getStores
     * @throws ClassCastException if an element of <code>stores</code> is not
     *             a {@link Store}.
     */
    public void setStores(List stores)
    {
        if (stores == null)
        {
            this.stores = new ArrayList();
        }
        else
        {
            for (Iterator i = stores.iterator(); i.hasNext();)
            {
                if (!(i.next() instanceof Store))
                {
                    throw new ClassCastException(
                        "All elements of list must be "
                            + "of type org.bouncycastle.util.Store.");
                }
            }
            this.stores = new ArrayList(stores);
        }
    }

    /**
     * Adds a Bouncy Castle {@link Store} to find CRLs, certificates, attribute
     * certificates or cross certificates.
     * <p>
     * This method should be used to add local stores, like collection based
     * X.509 stores, if available. Local stores should be considered first,
     * before trying to use additional (remote) locations, because they do not
     * need possible additional network traffic.
     * <p>
     * If <code>store</code> is <code>null</code> it is ignored.
     * 
     * @param store The store to add.
     * @see #getStores
     */
    public void addStore(Store store)
    {
        if (store != null)
        {
            stores.add(store);
        }
    }

    /**
     * Adds an additional Bouncy Castle {@link Store} to find CRLs, certificates,
     * attribute certificates or cross certificates.
     * <p>
     * You should not use this method. This method is used for adding additional
     * X.509 stores, which are used to add (remote) locations, e.g. LDAP, found
     * during X.509 object processing, e.g. in certificates or CRLs. This method
     * is used in PKIX certification path processing.
     * <p>
     * If <code>store</code> is <code>null</code> it is ignored.
     * 
     * @param store The store to add.
     * @see #getStores()
     * @deprectaed use addStore().
     */
    public void addAdditionalStore(Store store)
    {
        if (store != null)
        {
            additionalStores.add(store);
        }
    }

    /**
     * @deprecated
     */
    public void addAddionalStore(Store store)
    {
        addAdditionalStore(store);      
    }

    /**
     * Returns an immutable <code>List</code> of additional Bouncy Castle
     * <code>Store</code>s used for finding CRLs, certificates, attribute
     * certificates or cross certificates.
     * 
     * @return an immutable <code>List</code> of additional Bouncy Castle
     *         <code>Store</code>s. Never <code>null</code>.
     * 
     * @see #addAdditionalStore(Store)
     */
    public List getAdditionalStores()
    {
        return Collections.unmodifiableList(additionalStores);
    }

    /**
     * Returns an immutable <code>List</code> of Bouncy Castle
     * <code>Store</code>s used for finding CRLs, certificates, attribute
     * certificates or cross certificates.
     * 
     * @return an immutable <code>List</code> of Bouncy Castle
     *         <code>Store</code>s. Never <code>null</code>.
     * 
     * @see #setStores(List)
     */
    public List getStores()
    {
        return Collections.unmodifiableList(new ArrayList(stores));
    }

    /**
     * @param validityModel The validity model to set.
     * @see #CHAIN_VALIDITY_MODEL
     * @see #PKIX_VALIDITY_MODEL
     */
    public void setValidityModel(int validityModel)
    {
        this.validityModel = validityModel;
    }

    public Object clone()
    {
        ExtendedPKIXParameters params;
        try
        {
            params = new ExtendedPKIXParameters(getTrustAnchors());
        }
        catch (Exception e)
        {
            // cannot happen
            throw new RuntimeException(e.getMessage());
        }
        params.setParams(this);
        return params;
    }

    /**
     * Returns if additional {@link X509Store}s for locations like LDAP found
     * in certificates or CRLs should be used.
     * 
     * @return Returns <code>true</code> if additional stores are used.
     */
    public boolean isAdditionalLocationsEnabled()
    {
        return additionalLocationsEnabled;
    }

    /**
     * Sets if additional {@link X509Store}s for locations like LDAP found in
     * certificates or CRLs should be used.
     * 
     * @param enabled <code>true</code> if additional stores are used.
     */
    public void setAdditionalLocationsEnabled(boolean enabled)
    {
        additionalLocationsEnabled = enabled;
    }

    /**
     * Returns the required constraints on the target certificate or attribute
     * certificate. The constraints are returned as an instance of
     * <code>Selector</code>. If <code>null</code>, no constraints are
     * defined.
     * 
     * <p>
     * The target certificate in a PKIX path may be a certificate or an
     * attribute certificate.
     * <p>
     * Note that the <code>Selector</code> returned is cloned to protect
     * against subsequent modifications.
     * 
     * @return a <code>Selector</code> specifying the constraints on the
     *         target certificate or attribute certificate (or <code>null</code>)
     * @see #setTargetConstraints
     * @see X509CertStoreSelector
     * @see X509AttributeCertStoreSelector
     */
    public Selector getTargetConstraints()
    {
        if (selector != null)
        {
            return (Selector) selector.clone();
        }
        else
        {
            return null;
        }
    }

    /**
     * Sets the required constraints on the target certificate or attribute
     * certificate. The constraints are specified as an instance of
     * <code>Selector</code>. If <code>null</code>, no constraints are
     * defined.
     * <p>
     * The target certificate in a PKIX path may be a certificate or an
     * attribute certificate.
     * <p>
     * Note that the <code>Selector</code> specified is cloned to protect
     * against subsequent modifications.
     * 
     * @param selector a <code>Selector</code> specifying the constraints on
     *            the target certificate or attribute certificate (or
     *            <code>null</code>)
     * @see #getTargetConstraints
     * @see X509CertStoreSelector
     * @see X509AttributeCertStoreSelector
     */
    public void setTargetConstraints(Selector selector)
    {
        if (selector != null)
        {
            this.selector = (Selector) selector.clone();
        }
        else
        {
            this.selector = null;
        }
    }

    /**
     * Sets the required constraints on the target certificate. The constraints
     * are specified as an instance of <code>X509CertSelector</code>. If
     * <code>null</code>, no constraints are defined.
     * 
     * <p>
     * This method wraps the given <code>X509CertSelector</code> into a
     * <code>X509CertStoreSelector</code>.
     * <p>
     * Note that the <code>X509CertSelector</code> specified is cloned to
     * protect against subsequent modifications.
     * 
     * @param selector a <code>X509CertSelector</code> specifying the
     *            constraints on the target certificate (or <code>null</code>)
     * @see #getTargetCertConstraints
     * @see X509CertStoreSelector
     */
    public void setTargetCertConstraints(CertSelector selector)
    {
        super.setTargetCertConstraints(selector);
        if (selector != null)
        {
            this.selector = X509CertStoreSelector
                .getInstance((X509CertSelector) selector);
        }
        else
        {
            this.selector = null;
        }
    }

    /**
     * Returns the trusted attribute certificate issuers. If attribute
     * certificates is verified the trusted AC issuers must be set.
     * <p>
     * The returned <code>Set</code> consists of <code>TrustAnchor</code>s.
     * <p>
     * The returned <code>Set</code> is immutable. Never <code>null</code>
     * 
     * @return Returns an immutable set of the trusted AC issuers.
     */
    public Set getTrustedACIssuers()
    {
        return Collections.unmodifiableSet(trustedACIssuers);
    }

    /**
     * Sets the trusted attribute certificate issuers. If attribute certificates
     * is verified the trusted AC issuers must be set.
     * <p>
     * The <code>trustedACIssuers</code> must be a <code>Set</code> of
     * <code>TrustAnchor</code>
     * <p>
     * The given set is cloned.
     * 
     * @param trustedACIssuers The trusted AC issuers to set. Is never
     *            <code>null</code>.
     * @throws ClassCastException if an element of <code>stores</code> is not
     *             a <code>TrustAnchor</code>.
     */
    public void setTrustedACIssuers(Set trustedACIssuers)
    {
        if (trustedACIssuers == null)
        {
            this.trustedACIssuers.clear();
            return;
        }
        for (Iterator it = trustedACIssuers.iterator(); it.hasNext();)
        {
            if (!(it.next() instanceof TrustAnchor))
            {
                throw new ClassCastException("All elements of set must be "
                    + "of type " + TrustAnchor.class.getName() + ".");
            }
        }
        this.trustedACIssuers.clear();
        this.trustedACIssuers.addAll(trustedACIssuers);
    }

    /**
     * Returns the neccessary attributes which must be contained in an attribute
     * certificate.
     * <p>
     * The returned <code>Set</code> is immutable and contains
     * <code>String</code>s with the OIDs.
     * 
     * @return Returns the necessary AC attributes.
     */
    public Set getNecessaryACAttributes()
    {
        return Collections.unmodifiableSet(necessaryACAttributes);
    }

    /**
     * Sets the neccessary which must be contained in an attribute certificate.
     * <p>
     * The <code>Set</code> must contain <code>String</code>s with the
     * OIDs.
     * <p>
     * The set is cloned.
     * 
     * @param necessaryACAttributes The necessary AC attributes to set.
     * @throws ClassCastException if an element of
     *             <code>necessaryACAttributes</code> is not a
     *             <code>String</code>.
     */
    public void setNecessaryACAttributes(Set necessaryACAttributes)
    {
        if (necessaryACAttributes == null)
        {
            this.necessaryACAttributes.clear();
            return;
        }
        for (Iterator it = necessaryACAttributes.iterator(); it.hasNext();)
        {
            if (!(it.next() instanceof String))
            {
                throw new ClassCastException("All elements of set must be "
                    + "of type String.");
            }
        }
        this.necessaryACAttributes.clear();
        this.necessaryACAttributes.addAll(necessaryACAttributes);
    }

    /**
     * Returns the attribute certificates which are not allowed.
     * <p>
     * The returned <code>Set</code> is immutable and contains
     * <code>String</code>s with the OIDs.
     * 
     * @return Returns the prohibited AC attributes. Is never <code>null</code>.
     */
    public Set getProhibitedACAttributes()
    {
        return Collections.unmodifiableSet(prohibitedACAttributes);
    }

    /**
     * Sets the attribute certificates which are not allowed.
     * <p>
     * The <code>Set</code> must contain <code>String</code>s with the
     * OIDs.
     * <p>
     * The set is cloned.
     * 
     * @param prohibitedACAttributes The prohibited AC attributes to set.
     * @throws ClassCastException if an element of
     *             <code>prohibitedACAttributes</code> is not a
     *             <code>String</code>.
     */
    public void setProhibitedACAttributes(Set prohibitedACAttributes)
    {
        if (prohibitedACAttributes == null)
        {
            this.prohibitedACAttributes.clear();
            return;
        }
        for (Iterator it = prohibitedACAttributes.iterator(); it.hasNext();)
        {
            if (!(it.next() instanceof String))
            {
                throw new ClassCastException("All elements of set must be "
                    + "of type String.");
            }
        }
        this.prohibitedACAttributes.clear();
        this.prohibitedACAttributes.addAll(prohibitedACAttributes);
    }

    /**
     * Returns the attribute certificate checker. The returned set contains
     * {@link PKIXAttrCertChecker}s and is immutable.
     * 
     * @return Returns the attribute certificate checker. Is never
     *         <code>null</code>.
     */
    public Set getAttrCertCheckers()
    {
        return Collections.unmodifiableSet(attrCertCheckers);
    }

    /**
     * Sets the attribute certificate checkers.
     * <p>
     * All elements in the <code>Set</code> must a {@link PKIXAttrCertChecker}.
     * <p>
     * The given set is cloned.
     * 
     * @param attrCertCheckers The attribute certificate checkers to set. Is
     *            never <code>null</code>.
     * @throws ClassCastException if an element of <code>attrCertCheckers</code>
     *             is not a <code>PKIXAttrCertChecker</code>.
     */
    public void setAttrCertCheckers(Set attrCertCheckers)
    {
        if (attrCertCheckers == null)
        {
            this.attrCertCheckers.clear();
            return;
        }
        for (Iterator it = attrCertCheckers.iterator(); it.hasNext();)
        {
            if (!(it.next() instanceof PKIXAttrCertChecker))
            {
                throw new ClassCastException("All elements of set must be "
                    + "of type " + PKIXAttrCertChecker.class.getName() + ".");
            }
        }
        this.attrCertCheckers.clear();
        this.attrCertCheckers.addAll(attrCertCheckers);
    }

}
