package org.bouncycastle.jcajce.provider.asymmetric.x509;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.security.cert.CRL;
import java.security.cert.CRLException;
import java.security.cert.CertPath;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactorySpi;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.SignedData;
import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.asn1.x509.CertificateList;
import org.bouncycastle.jcajce.util.BCJcaJceHelper;
import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.util.io.Streams;

/**
 * class for dealing with X509 certificates.
 * <p>
 * At the moment this will deal with "-----BEGIN CERTIFICATE-----" to "-----END CERTIFICATE-----"
 * base 64 encoded certs, as well as the BER binaries of certificates and some classes of PKCS#7
 * objects.
 */
public class CertificateFactory
    extends CertificateFactorySpi
{
    private final JcaJceHelper bcHelper = new BCJcaJceHelper();

    private static final PEMUtil PEM_CERT_PARSER = new PEMUtil("CERTIFICATE");
    private static final PEMUtil PEM_CRL_PARSER = new PEMUtil("CRL");

    private ASN1Set sData = null;
    private int                sDataObjectCount = 0;
    private InputStream currentStream = null;
    
    private ASN1Set sCrlData = null;
    private int                sCrlDataObjectCount = 0;
    private InputStream currentCrlStream = null;

    private java.security.cert.Certificate readDERCertificate(
        ASN1InputStream dIn)
        throws IOException, CertificateParsingException
    {
        ASN1Sequence seq = (ASN1Sequence)dIn.readObject();

        if (seq.size() > 1
                && seq.getObjectAt(0) instanceof ASN1ObjectIdentifier)
        {
            if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData))
            {
                sData = SignedData.getInstance(ASN1Sequence.getInstance(
                    (ASN1TaggedObject)seq.getObjectAt(1), true)).getCertificates();

                return getCertificate();
            }
        }

        return new X509CertificateObject(bcHelper,
                            Certificate.getInstance(seq));
    }

    private java.security.cert.Certificate getCertificate()
        throws CertificateParsingException
    {
        if (sData != null)
        {
            while (sDataObjectCount < sData.size())
            {
                Object obj = sData.getObjectAt(sDataObjectCount++);

                if (obj instanceof ASN1Sequence)
                {
                   return new X509CertificateObject(bcHelper,
                                    Certificate.getInstance(obj));
                }
            }
        }

        return null;
    }

    private java.security.cert.Certificate readPEMCertificate(
        InputStream in)
        throws IOException, CertificateParsingException
    {
        ASN1Sequence seq = PEM_CERT_PARSER.readPEMObject(in);

        if (seq != null)
        {
            return new X509CertificateObject(bcHelper,
                            Certificate.getInstance(seq));
        }

        return null;
    }

    protected CRL createCRL(CertificateList c)
    throws CRLException
    {
        return new X509CRLObject(bcHelper, c);
    }
    
    private CRL readPEMCRL(
        InputStream in)
        throws IOException, CRLException
    {
        ASN1Sequence seq = PEM_CRL_PARSER.readPEMObject(in);

        if (seq != null)
        {
            return createCRL(
                            CertificateList.getInstance(seq));
        }

        return null;
    }

    private CRL readDERCRL(
        ASN1InputStream aIn)
        throws IOException, CRLException
    {
        ASN1Sequence seq = (ASN1Sequence)aIn.readObject();

        if (seq.size() > 1
                && seq.getObjectAt(0) instanceof ASN1ObjectIdentifier)
        {
            if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData))
            {
                sCrlData = SignedData.getInstance(ASN1Sequence.getInstance(
                    (ASN1TaggedObject)seq.getObjectAt(1), true)).getCRLs();
    
                return getCRL();
            }
        }

        return createCRL(
                     CertificateList.getInstance(seq));
    }

    private CRL getCRL()
        throws CRLException
    {
        if (sCrlData == null || sCrlDataObjectCount >= sCrlData.size())
        {
            return null;
        }

        return createCRL(
                            CertificateList.getInstance(
                                sCrlData.getObjectAt(sCrlDataObjectCount++)));
    }

    /**
     * Generates a certificate object and initializes it with the data
     * read from the input stream inStream.
     */
    public java.security.cert.Certificate engineGenerateCertificate(
        InputStream in)
        throws CertificateException
    {
        if (currentStream == null)
        {
            currentStream = in;
            sData = null;
            sDataObjectCount = 0;
        }
        else if (currentStream != in) // reset if input stream has changed
        {
            currentStream = in;
            sData = null;
            sDataObjectCount = 0;
        }

        try
        {
            if (sData != null)
            {
                if (sDataObjectCount != sData.size())
                {
                    return getCertificate();
                }
                else
                {
                    sData = null;
                    sDataObjectCount = 0;
                    return null;
                }
            }

            InputStream pis;

            if (in.markSupported())
            {
                pis = in;
            }
            else
            {
                // BEGIN android-changed
                // Was: pis = new ByteArrayInputStream(Streams.readAll(in));
                // Reason: we want {@code in.available()} to return the number of available bytes if
                // there is trailing data (otherwise it breaks
                // libcore.java.security.cert.X509CertificateTest#test_Provider
                // ). Which is not possible if we read the whole stream at this point.
                pis = new PushbackInputStream(in);
                // END android-changed
            }

            // BEGIN android-changed
            // Was: pis.mark(1);
            if (in.markSupported()) {
                pis.mark(1);
            }
            // END android-changed

            int tag = pis.read();

            if (tag == -1)
            {
                return null;
            }

            // BEGIN android-changdd
            // Was: pis.reset
            if (in.markSupported()) {
                pis.reset();
            }
            else
            {
                ((PushbackInputStream) pis).unread(tag);
            }
            // END android-changed

            if (tag != 0x30)  // assume ascii PEM encoded.
            {
                return readPEMCertificate(pis);
            }
            else
            {
                return readDERCertificate(new ASN1InputStream(pis));
            }
        }
        catch (Exception e)
        {
            throw new ExCertificateException(e);
        }
    }

    /**
     * Returns a (possibly empty) collection view of the certificates
     * read from the given input stream inStream.
     */
    public Collection engineGenerateCertificates(
        InputStream inStream)
        throws CertificateException
    {
        java.security.cert.Certificate     cert;
        // BEGIN android-removed
        // BufferedInputStream in = new BufferedInputStream(inStream);
        // Reason: we want {@code in.available()} to return the number of available bytes if
        // there is trailing data (otherwise it breaks
        // libcore.java.security.cert.X509CertificateTest#test_Provider
        // ). Which is not possible if we read the whole stream at this point.
        // END android-removed
        List certs = new ArrayList();

        // BEGIN android-changed
        // Was: while ((cert = engineGenerateCertificate(in)) != null)
        while ((cert = engineGenerateCertificate(inStream)) != null)
        // END android-changed
        {
            certs.add(cert);
        }

        return certs;
    }

    /**
     * Generates a certificate revocation list (CRL) object and initializes
     * it with the data read from the input stream inStream.
     */
    public CRL engineGenerateCRL(
        InputStream in)
        throws CRLException
    {
        if (currentCrlStream == null)
        {
            currentCrlStream = in;
            sCrlData = null;
            sCrlDataObjectCount = 0;
        }
        else if (currentCrlStream != in) // reset if input stream has changed
        {
            currentCrlStream = in;
            sCrlData = null;
            sCrlDataObjectCount = 0;
        }

        try
        {
            if (sCrlData != null)
            {
                if (sCrlDataObjectCount != sCrlData.size())
                {
                    return getCRL();
                }
                else
                {
                    sCrlData = null;
                    sCrlDataObjectCount = 0;
                    return null;
                }
            }

            InputStream pis;

            if (in.markSupported())
            {
                pis = in;
            }
            else
            {
                pis = new ByteArrayInputStream(Streams.readAll(in));
            }

            pis.mark(1);
            int tag = pis.read();

            if (tag == -1)
            {
                return null;
            }

            pis.reset();
            if (tag != 0x30)  // assume ascii PEM encoded.
            {
                return readPEMCRL(pis);
            }
            else
            {       // lazy evaluate to help processing of large CRLs
                return readDERCRL(new ASN1InputStream(pis, true));
            }
        }
        catch (CRLException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            throw new CRLException(e.toString());
        }
    }

    /**
     * Returns a (possibly empty) collection view of the CRLs read from
     * the given input stream inStream.
     *
     * The inStream may contain a sequence of DER-encoded CRLs, or
     * a PKCS#7 CRL set.  This is a PKCS#7 SignedData object, with the
     * only signficant field being crls.  In particular the signature
     * and the contents are ignored.
     */
    public Collection engineGenerateCRLs(
        InputStream inStream)
        throws CRLException
    {
        CRL crl;
        List crls = new ArrayList();
        BufferedInputStream in = new BufferedInputStream(inStream);

        while ((crl = engineGenerateCRL(in)) != null)
        {
            crls.add(crl);
        }

        return crls;
    }

    public Iterator engineGetCertPathEncodings()
    {
        return PKIXCertPath.certPathEncodings.iterator();
    }

    public CertPath engineGenerateCertPath(
        InputStream inStream)
        throws CertificateException
    {
        return engineGenerateCertPath(inStream, "PkiPath");
    }

    public CertPath engineGenerateCertPath(
        InputStream inStream,
        String encoding)
        throws CertificateException
    {
        return new PKIXCertPath(inStream, encoding);
    }

    public CertPath engineGenerateCertPath(
        List certificates)
        throws CertificateException
    {
        Iterator iter = certificates.iterator();
        Object obj;
        while (iter.hasNext())
        {
            obj = iter.next();
            if (obj != null)
            {
                if (!(obj instanceof X509Certificate))
                {
                    throw new CertificateException("list contains non X509Certificate object while creating CertPath\n" + obj.toString());
                }
            }
        }
        return new PKIXCertPath(certificates);
    }

    private class ExCertificateException
        extends CertificateException
    {
        private Throwable cause;

        public ExCertificateException(Throwable cause)
        {
            this.cause = cause;
        }

        public ExCertificateException(String msg, Throwable cause)
        {
            super(msg);

            this.cause = cause;
        }

        public Throwable getCause()
        {
            return cause;
        }
    }
}
