package org.bouncycastle.x509;

import org.bouncycastle.util.Selector;

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidParameterException;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509CertSelector;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
 * This class contains extended parameters for PKIX certification path builders.
 * 
 * @see java.security.cert.PKIXBuilderParameters
 * @see org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi
 * @deprecated use PKIXExtendedBuilderParameters
 */
public class ExtendedPKIXBuilderParameters extends ExtendedPKIXParameters
{

    private int maxPathLength = 5;

    private Set excludedCerts = Collections.EMPTY_SET;

    /**
     * Excluded certificates are not used for building a certification path.
     * <p>
     * The returned set is immutable.
     * 
     * @return Returns the excluded certificates.
     */
    public Set getExcludedCerts()
    {
        return Collections.unmodifiableSet(excludedCerts);
    }

    /**
     * Sets the excluded certificates which are not used for building a
     * certification path. If the <code>Set</code> is <code>null</code> an
     * empty set is assumed.
     * <p>
     * The given set is cloned to protect it against subsequent modifications.
     * 
     * @param excludedCerts The excluded certificates to set.
     */
    public void setExcludedCerts(Set excludedCerts)
    {
        if (excludedCerts == null)
        {
            excludedCerts = Collections.EMPTY_SET;
        }
        else
        {
            this.excludedCerts = new HashSet(excludedCerts);
        }
    }

    /**
     * Creates an instance of <code>PKIXBuilderParameters</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.
     * 
     * @param trustAnchors a <code>Set</code> of <code>TrustAnchor</code>s
     * @param targetConstraints a <code>Selector</code> specifying the
     *            constraints on the target certificate or attribute
     *            certificate.
     * @throws InvalidAlgorithmParameterException if <code>trustAnchors</code>
     *             is empty.
     * @throws NullPointerException if <code>trustAnchors</code> is
     *             <code>null</code>
     * @throws ClassCastException if any of the elements of
     *             <code>trustAnchors</code> is not of type
     *             <code>java.security.cert.TrustAnchor</code>
     */
    public ExtendedPKIXBuilderParameters(Set trustAnchors,
            Selector targetConstraints)
            throws InvalidAlgorithmParameterException
    {
        super(trustAnchors);
        setTargetConstraints(targetConstraints);
    }

    /**
     * Sets the maximum number of intermediate non-self-issued certificates in a
     * certification path. The PKIX <code>CertPathBuilder</code> must not
     * build paths longer then this length.
     * <p>
     * A value of 0 implies that the path can only contain a single certificate.
     * A value of -1 does not limit the length. The default length is 5.
     * 
     * <p>
     * 
     * The basic constraints extension of a CA certificate overrides this value
     * if smaller.
     * 
     * @param maxPathLength the maximum number of non-self-issued intermediate
     *            certificates in the certification path
     * @throws InvalidParameterException if <code>maxPathLength</code> is set
     *             to a value less than -1
     * 
     * @see org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi
     * @see #getMaxPathLength
     */
    public void setMaxPathLength(int maxPathLength)
    {
        if (maxPathLength < -1)
        {
            throw new InvalidParameterException("The maximum path "
                    + "length parameter can not be less than -1.");
        }
        this.maxPathLength = maxPathLength;
    }

    /**
     * Returns the value of the maximum number of intermediate non-self-issued
     * certificates in the certification path.
     * 
     * @return the maximum number of non-self-issued intermediate certificates
     *         in the certification path, or -1 if no limit exists.
     * 
     * @see #setMaxPathLength(int)
     */
    public int getMaxPathLength()
    {
        return maxPathLength;
    }

    /**
     * Can alse handle <code>ExtendedPKIXBuilderParameters</code> and
     * <code>PKIXBuilderParameters</code>.
     * 
     * @param params Parameters to set.
     * @see org.bouncycastle.x509.ExtendedPKIXParameters#setParams(java.security.cert.PKIXParameters)
     */
    protected void setParams(PKIXParameters params)
    {
        super.setParams(params);
        if (params instanceof ExtendedPKIXBuilderParameters)
        {
            ExtendedPKIXBuilderParameters _params = (ExtendedPKIXBuilderParameters) params;
            maxPathLength = _params.maxPathLength;
            excludedCerts = new HashSet(_params.excludedCerts);
        }
        if (params instanceof PKIXBuilderParameters)
        {
            PKIXBuilderParameters _params = (PKIXBuilderParameters) params;
            maxPathLength = _params.getMaxPathLength();
        }
    }

    /**
     * Makes a copy of this <code>PKIXParameters</code> object. Changes to the
     * copy will not affect the original and vice versa.
     * 
     * @return a copy of this <code>PKIXParameters</code> object
     */
    public Object clone()
    {
        ExtendedPKIXBuilderParameters params = null;
        try
        {
            params = new ExtendedPKIXBuilderParameters(getTrustAnchors(),
                    getTargetConstraints());
        }
        catch (Exception e)
        {
            // cannot happen
            throw new RuntimeException(e.getMessage());
        }
        params.setParams(this);
        return params;
    }

    /**
     * Returns an instance of <code>ExtendedPKIXParameters</code> which can be
     * safely casted to <code>ExtendedPKIXBuilderParameters</code>.
     * <p>
     * This method can be used to get a copy from other
     * <code>PKIXBuilderParameters</code>, <code>PKIXParameters</code>,
     * and <code>ExtendedPKIXParameters</code> instances.
     * 
     * @param pkixParams The PKIX parameters to create a copy of.
     * @return An <code>ExtendedPKIXBuilderParameters</code> instance.
     */
    public static ExtendedPKIXParameters getInstance(PKIXParameters pkixParams)
    {
        ExtendedPKIXBuilderParameters params;
        try
        {
            params = new ExtendedPKIXBuilderParameters(pkixParams
                    .getTrustAnchors(), X509CertStoreSelector
                    .getInstance((X509CertSelector) pkixParams
                            .getTargetCertConstraints()));
        }
        catch (Exception e)
        {
            // cannot happen
            throw new RuntimeException(e.getMessage());
        }
        params.setParams(pkixParams);
        return params;
    }
}
