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

package org.bouncycastle.crypto.util;

import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import java.io.FileInputStream;
import org.bouncycastle.util.io.Streams;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.io.File;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Sequence;
import java.security.SecureRandom;
import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import java.io.Serializable;
import org.bouncycastle.util.Encodable;

public class JournaledAlgorithm implements Encodable, Serializable
{
    private transient JournalingSecureRandom journaling;
    private transient AlgorithmIdentifier algID;
    
    public JournaledAlgorithm(final AlgorithmIdentifier algID, final JournalingSecureRandom journaling) {
        if (algID == null) {
            throw new NullPointerException("AlgorithmIdentifier passed to JournaledAlgorithm is null");
        }
        if (journaling == null) {
            throw new NullPointerException("JournalingSecureRandom passed to JournaledAlgorithm is null");
        }
        this.journaling = journaling;
        this.algID = algID;
    }
    
    public JournaledAlgorithm(final byte[] array) {
        this(array, CryptoServicesRegistrar.getSecureRandom());
    }
    
    public JournaledAlgorithm(final byte[] array, final SecureRandom secureRandom) {
        if (array == null) {
            throw new NullPointerException("encoding passed to JournaledAlgorithm is null");
        }
        if (secureRandom == null) {
            throw new NullPointerException("random passed to JournaledAlgorithm is null");
        }
        this.initFromEncoding(array, secureRandom);
    }
    
    private void initFromEncoding(final byte[] array, final SecureRandom secureRandom) {
        final ASN1Sequence instance = ASN1Sequence.getInstance(array);
        this.algID = AlgorithmIdentifier.getInstance(instance.getObjectAt(0));
        this.journaling = new JournalingSecureRandom(ASN1OctetString.getInstance(instance.getObjectAt(1)).getOctets(), secureRandom);
    }
    
    public JournalingSecureRandom getJournalingSecureRandom() {
        return this.journaling;
    }
    
    public AlgorithmIdentifier getAlgorithmIdentifier() {
        return this.algID;
    }
    
    public void storeState(final File file) throws IOException {
        if (file == null) {
            throw new NullPointerException("file for storage is null in JournaledAlgorithm");
        }
        final FileOutputStream fileOutputStream = new FileOutputStream(file);
        try {
            this.storeState(fileOutputStream);
        }
        finally {
            fileOutputStream.close();
        }
    }
    
    public void storeState(final OutputStream outputStream) throws IOException {
        if (outputStream == null) {
            throw new NullPointerException("output stream for storage is null in JournaledAlgorithm");
        }
        outputStream.write(this.getEncoded());
    }
    
    public static JournaledAlgorithm getState(final InputStream in, final SecureRandom secureRandom) throws IOException, ClassNotFoundException {
        if (in == null) {
            throw new NullPointerException("stream for loading is null in JournaledAlgorithm");
        }
        final BufferedInputStream bufferedInputStream = new BufferedInputStream(in);
        try {
            return new JournaledAlgorithm(Streams.readAll(bufferedInputStream), secureRandom);
        }
        finally {
            bufferedInputStream.close();
        }
    }
    
    public static JournaledAlgorithm getState(final File file, final SecureRandom secureRandom) throws IOException, ClassNotFoundException {
        if (file == null) {
            throw new NullPointerException("File for loading is null in JournaledAlgorithm");
        }
        final BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
        try {
            return new JournaledAlgorithm(Streams.readAll(bufferedInputStream), secureRandom);
        }
        finally {
            bufferedInputStream.close();
        }
    }
    
    @Override
    public byte[] getEncoded() throws IOException {
        final ASN1EncodableVector asn1EncodableVector = new ASN1EncodableVector();
        asn1EncodableVector.add(this.algID);
        asn1EncodableVector.add(new DEROctetString(this.journaling.getFullTranscript()));
        return new DERSequence(asn1EncodableVector).getEncoded();
    }
    
    private void readObject(final ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
        objectInputStream.defaultReadObject();
        this.initFromEncoding((byte[])objectInputStream.readObject(), CryptoServicesRegistrar.getSecureRandom());
    }
    
    private void writeObject(final ObjectOutputStream objectOutputStream) throws IOException {
        objectOutputStream.defaultWriteObject();
        objectOutputStream.writeObject(this.getEncoded());
    }
}
