package org.bouncycastle.tsp.cms;

import java.io.IOException;
import java.io.OutputStream;

import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.cms.AttributeTable;
import org.bouncycastle.asn1.cms.ContentInfo;
import org.bouncycastle.asn1.cms.Evidence;
import org.bouncycastle.asn1.cms.TimeStampAndCRL;
import org.bouncycastle.asn1.cms.TimeStampedData;
import org.bouncycastle.asn1.cms.TimeStampedDataParser;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.operator.DigestCalculator;
import org.bouncycastle.operator.DigestCalculatorProvider;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.tsp.TSPException;
import org.bouncycastle.tsp.TimeStampToken;
import org.bouncycastle.tsp.TimeStampTokenInfo;
import org.bouncycastle.util.Arrays;

class TimeStampDataUtil
{
    private final TimeStampAndCRL[] timeStamps;

    private final MetaDataUtil      metaDataUtil;

    TimeStampDataUtil(TimeStampedData timeStampedData)
    {
        this.metaDataUtil = new MetaDataUtil(timeStampedData.getMetaData());

        Evidence evidence = timeStampedData.getTemporalEvidence();
        this.timeStamps = evidence.getTstEvidence().toTimeStampAndCRLArray();
    }

    TimeStampDataUtil(TimeStampedDataParser timeStampedData)
        throws IOException
    {       
        this.metaDataUtil = new MetaDataUtil(timeStampedData.getMetaData());

        Evidence evidence = timeStampedData.getTemporalEvidence();
        this.timeStamps = evidence.getTstEvidence().toTimeStampAndCRLArray();
    }

    TimeStampToken getTimeStampToken(TimeStampAndCRL timeStampAndCRL)
        throws CMSException
    {
        ContentInfo timeStampToken = timeStampAndCRL.getTimeStampToken();

        try
        {
            TimeStampToken token = new TimeStampToken(timeStampToken);
            return token;
        }
        catch (IOException e)
        {
            throw new CMSException("unable to parse token data: " + e.getMessage(), e);
        }
        catch (TSPException e)
        {
            if (e.getCause() instanceof CMSException)
            {
                throw (CMSException)e.getCause();
            }

            throw new CMSException("token data invalid: " + e.getMessage(), e);
        }
        catch (IllegalArgumentException e)
        {
            throw new CMSException("token data invalid: " + e.getMessage(), e);
        }
    }

    void initialiseMessageImprintDigestCalculator(DigestCalculator calculator)
        throws CMSException
    {
        metaDataUtil.initialiseMessageImprintDigestCalculator(calculator);
    }

    DigestCalculator getMessageImprintDigestCalculator(DigestCalculatorProvider calculatorProvider)
        throws OperatorCreationException
    {
        TimeStampToken token;

        try
        {
            token = this.getTimeStampToken(timeStamps[0]);

            TimeStampTokenInfo info = token.getTimeStampInfo();
            ASN1ObjectIdentifier algOID = info.getMessageImprintAlgOID();

            DigestCalculator calc = calculatorProvider.get(new AlgorithmIdentifier(algOID));

            initialiseMessageImprintDigestCalculator(calc);

            return calc;
        }
        catch (CMSException e)
        {
            throw new OperatorCreationException("unable to extract algorithm ID: " + e.getMessage(), e);
        }
    }

    TimeStampToken[] getTimeStampTokens()
        throws CMSException
    {
        TimeStampToken[] tokens = new TimeStampToken[timeStamps.length];
        for (int i = 0; i < timeStamps.length; i++)
        {
            tokens[i] = this.getTimeStampToken(timeStamps[i]);
        }

        return tokens;
    }

    TimeStampAndCRL[] getTimeStamps()
    {
        return timeStamps;
    }

    byte[] calculateNextHash(DigestCalculator calculator)
        throws CMSException
    {
        TimeStampAndCRL tspToken = timeStamps[timeStamps.length - 1];

        OutputStream out = calculator.getOutputStream();

        try
        {
            out.write(tspToken.getEncoded(ASN1Encoding.DER));

            out.close();

            return calculator.getDigest();
        }
        catch (IOException e)
        {
            throw new CMSException("exception calculating hash: " + e.getMessage(), e);
        }
    }

    /**
     * Validate the digests present in the TimeStampTokens contained in the CMSTimeStampedData.
     */
    void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest)
        throws ImprintDigestInvalidException, CMSException
    {
        byte[] currentDigest = dataDigest;

        for (int i = 0; i < timeStamps.length; i++)
        {
            try
            {
                TimeStampToken token = this.getTimeStampToken(timeStamps[i]);
                if (i > 0)
                {
                    TimeStampTokenInfo info = token.getTimeStampInfo();
                    DigestCalculator calculator = calculatorProvider.get(info.getHashAlgorithm());

                    calculator.getOutputStream().write(timeStamps[i - 1].getEncoded(ASN1Encoding.DER));

                    currentDigest = calculator.getDigest();
                }

                this.compareDigest(token, currentDigest);
            }
            catch (IOException e)
            {
                throw new CMSException("exception calculating hash: " + e.getMessage(), e);
            }
            catch (OperatorCreationException e)
            {
                throw new CMSException("cannot create digest: " + e.getMessage(), e);
            }
        }
    }

    void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest, TimeStampToken timeStampToken)
        throws ImprintDigestInvalidException, CMSException
    {
        byte[] currentDigest = dataDigest;
        byte[] encToken;

        try
        {
            encToken = timeStampToken.getEncoded();
        }
        catch (IOException e)
        {
            throw new CMSException("exception encoding timeStampToken: " + e.getMessage(), e);
        }

        for (int i = 0; i < timeStamps.length; i++)
        {
            try
            {
                TimeStampToken token = this.getTimeStampToken(timeStamps[i]);
                if (i > 0)
                {
                    TimeStampTokenInfo info = token.getTimeStampInfo();
                    DigestCalculator calculator = calculatorProvider.get(info.getHashAlgorithm());

                    calculator.getOutputStream().write(timeStamps[i - 1].getEncoded(ASN1Encoding.DER));

                    currentDigest = calculator.getDigest();
                }

                this.compareDigest(token, currentDigest);

                if (Arrays.areEqual(token.getEncoded(), encToken))
                {
                    return;
                }
            }
            catch (IOException e)
            {
                throw new CMSException("exception calculating hash: " + e.getMessage(), e);
            }
            catch (OperatorCreationException e)
            {
                throw new CMSException("cannot create digest: " + e.getMessage(), e);
            }
        }

        throw new ImprintDigestInvalidException("passed in token not associated with timestamps present", timeStampToken);
    }

    private void compareDigest(TimeStampToken timeStampToken, byte[] digest)
        throws ImprintDigestInvalidException
    {
        TimeStampTokenInfo info = timeStampToken.getTimeStampInfo();
        byte[] tsrMessageDigest = info.getMessageImprintDigest();

        if (!Arrays.areEqual(digest, tsrMessageDigest))
        {
            throw new ImprintDigestInvalidException("hash calculated is different from MessageImprintDigest found in TimeStampToken", timeStampToken);
        }
    }

    String getFileName()
    {
        return metaDataUtil.getFileName();
    }

    String getMediaType()
    {
        return metaDataUtil.getMediaType();
    }

    AttributeTable getOtherMetaData()
    {
        return new AttributeTable(metaDataUtil.getOtherMetaData());
    }
}
