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

package org.bouncycastle.asn1.tsp;

import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.cms.SignedData;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.cms.ContentInfo;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.cms.Attributes;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.ASN1Object;

public class ArchiveTimeStamp extends ASN1Object
{
    private final AlgorithmIdentifier digestAlgorithm;
    private final Attributes attributes;
    private final ASN1Sequence reducedHashTree;
    private final ContentInfo timeStamp;
    
    public static ArchiveTimeStamp getInstance(final Object o) {
        if (o instanceof ArchiveTimeStamp) {
            return (ArchiveTimeStamp)o;
        }
        if (o != null) {
            return new ArchiveTimeStamp(ASN1Sequence.getInstance(o));
        }
        return null;
    }
    
    public ArchiveTimeStamp(final AlgorithmIdentifier algorithmIdentifier, final PartialHashtree[] array, final ContentInfo contentInfo) {
        this(algorithmIdentifier, null, array, contentInfo);
    }
    
    public ArchiveTimeStamp(final ContentInfo contentInfo) {
        this(null, null, null, contentInfo);
    }
    
    public ArchiveTimeStamp(final AlgorithmIdentifier digestAlgorithm, final Attributes attributes, final PartialHashtree[] array, final ContentInfo timeStamp) {
        this.digestAlgorithm = digestAlgorithm;
        this.attributes = attributes;
        if (array != null) {
            this.reducedHashTree = new DERSequence(array);
        }
        else {
            this.reducedHashTree = null;
        }
        this.timeStamp = timeStamp;
    }
    
    private ArchiveTimeStamp(final ASN1Sequence asn1Sequence) {
        if (asn1Sequence.size() < 1 || asn1Sequence.size() > 4) {
            throw new IllegalArgumentException("wrong sequence size in constructor: " + asn1Sequence.size());
        }
        AlgorithmIdentifier instance = null;
        Attributes instance2 = null;
        ASN1Sequence instance3 = null;
        for (int i = 0; i < asn1Sequence.size() - 1; ++i) {
            final ASN1Encodable object = asn1Sequence.getObjectAt(i);
            if (object instanceof ASN1TaggedObject) {
                final ASN1TaggedObject instance4 = ASN1TaggedObject.getInstance(object);
                switch (instance4.getTagNo()) {
                    case 0: {
                        instance = AlgorithmIdentifier.getInstance(instance4, false);
                        break;
                    }
                    case 1: {
                        instance2 = Attributes.getInstance(instance4, false);
                        break;
                    }
                    case 2: {
                        instance3 = ASN1Sequence.getInstance(instance4, false);
                        break;
                    }
                    default: {
                        throw new IllegalArgumentException("invalid tag no in constructor: " + instance4.getTagNo());
                    }
                }
            }
        }
        this.digestAlgorithm = instance;
        this.attributes = instance2;
        this.reducedHashTree = instance3;
        this.timeStamp = ContentInfo.getInstance(asn1Sequence.getObjectAt(asn1Sequence.size() - 1));
    }
    
    public AlgorithmIdentifier getDigestAlgorithmIdentifier() {
        if (this.digestAlgorithm != null) {
            return this.digestAlgorithm;
        }
        return this.getTimeStampInfo().getMessageImprint().getHashAlgorithm();
    }
    
    public byte[] getTimeStampDigestValue() {
        return this.getTimeStampInfo().getMessageImprint().getHashedMessage();
    }
    
    private TSTInfo getTimeStampInfo() {
        if (!this.timeStamp.getContentType().equals(CMSObjectIdentifiers.signedData)) {
            throw new IllegalStateException("cannot identify algorithm identifier for digest");
        }
        final SignedData instance = SignedData.getInstance(this.timeStamp.getContent());
        if (instance.getEncapContentInfo().getContentType().equals(PKCSObjectIdentifiers.id_ct_TSTInfo)) {
            return TSTInfo.getInstance(ASN1OctetString.getInstance(instance.getEncapContentInfo().getContent()).getOctets());
        }
        throw new IllegalStateException("cannot parse time stamp");
    }
    
    public AlgorithmIdentifier getDigestAlgorithm() {
        return this.digestAlgorithm;
    }
    
    public PartialHashtree getHashTreeLeaf() {
        if (this.reducedHashTree == null) {
            return null;
        }
        return PartialHashtree.getInstance(this.reducedHashTree.getObjectAt(0));
    }
    
    public PartialHashtree[] getReducedHashTree() {
        if (this.reducedHashTree == null) {
            return null;
        }
        final PartialHashtree[] array = new PartialHashtree[this.reducedHashTree.size()];
        for (int i = 0; i != array.length; ++i) {
            array[i] = PartialHashtree.getInstance(this.reducedHashTree.getObjectAt(i));
        }
        return array;
    }
    
    public ContentInfo getTimeStamp() {
        return this.timeStamp;
    }
    
    @Override
    public ASN1Primitive toASN1Primitive() {
        final ASN1EncodableVector asn1EncodableVector = new ASN1EncodableVector(4);
        if (this.digestAlgorithm != null) {
            asn1EncodableVector.add(new DERTaggedObject(false, 0, this.digestAlgorithm));
        }
        if (this.attributes != null) {
            asn1EncodableVector.add(new DERTaggedObject(false, 1, this.attributes));
        }
        if (this.reducedHashTree != null) {
            asn1EncodableVector.add(new DERTaggedObject(false, 2, this.reducedHashTree));
        }
        asn1EncodableVector.add(this.timeStamp);
        return new DERSequence(asn1EncodableVector);
    }
}
