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

package org.bouncycastle.mime.smime;

import org.bouncycastle.cms.RecipientInfoGenerator;
import org.bouncycastle.cms.OriginatorInformation;
import org.bouncycastle.cms.CMSAttributeTableGenerator;
import java.util.LinkedHashMap;
import java.io.IOException;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.mime.MimeIOException;
import org.bouncycastle.mime.encoding.Base64OutputStream;
import org.bouncycastle.util.Strings;
import org.bouncycastle.mime.Headers;
import java.util.Map;
import java.io.OutputStream;
import org.bouncycastle.operator.OutputEncryptor;
import org.bouncycastle.cms.CMSEnvelopedDataStreamGenerator;
import org.bouncycastle.mime.MimeWriter;

public class SMIMEEnvelopedWriter extends MimeWriter
{
    private final CMSEnvelopedDataStreamGenerator envGen;
    private final OutputEncryptor outEnc;
    private final OutputStream mimeOut;
    private final String contentTransferEncoding;
    
    private SMIMEEnvelopedWriter(final Builder builder, final OutputEncryptor outEnc, final OutputStream mimeOut) {
        super(new Headers(MimeWriter.mapToLines(builder.headers), builder.contentTransferEncoding));
        this.envGen = builder.envGen;
        this.contentTransferEncoding = builder.contentTransferEncoding;
        this.outEnc = outEnc;
        this.mimeOut = mimeOut;
    }
    
    @Override
    public OutputStream getContentStream() throws IOException {
        this.headers.dumpHeaders(this.mimeOut);
        this.mimeOut.write(Strings.toByteArray("\r\n"));
        try {
            OutputStream mimeOut = this.mimeOut;
            if ("base64".equals(this.contentTransferEncoding)) {
                mimeOut = new Base64OutputStream(mimeOut);
            }
            return new ContentOutputStream(this.envGen.open(SMimeUtils.createUnclosable(mimeOut), this.outEnc), mimeOut);
        }
        catch (final CMSException ex) {
            throw new MimeIOException(ex.getMessage(), ex);
        }
    }
    
    public static class Builder
    {
        private static final String[] stdHeaders;
        private static final String[] stdValues;
        private final CMSEnvelopedDataStreamGenerator envGen;
        private final Map<String, String> headers;
        String contentTransferEncoding;
        
        public Builder() {
            this.envGen = new CMSEnvelopedDataStreamGenerator();
            this.headers = new LinkedHashMap<String, String>();
            this.contentTransferEncoding = "base64";
            for (int i = 0; i != Builder.stdHeaders.length; ++i) {
                this.headers.put(Builder.stdHeaders[i], Builder.stdValues[i]);
            }
        }
        
        public Builder setBufferSize(final int bufferSize) {
            this.envGen.setBufferSize(bufferSize);
            return this;
        }
        
        public Builder setUnprotectedAttributeGenerator(final CMSAttributeTableGenerator unprotectedAttributeGenerator) {
            this.envGen.setUnprotectedAttributeGenerator(unprotectedAttributeGenerator);
            return this;
        }
        
        public Builder setOriginatorInfo(final OriginatorInformation originatorInfo) {
            this.envGen.setOriginatorInfo(originatorInfo);
            return this;
        }
        
        public Builder withHeader(final String s, final String s2) {
            this.headers.put(s, s2);
            return this;
        }
        
        public Builder addRecipientInfoGenerator(final RecipientInfoGenerator recipientInfoGenerator) {
            this.envGen.addRecipientInfoGenerator(recipientInfoGenerator);
            return this;
        }
        
        public SMIMEEnvelopedWriter build(final OutputStream outputStream, final OutputEncryptor outputEncryptor) {
            return new SMIMEEnvelopedWriter(this, outputEncryptor, SMimeUtils.autoBuffer(outputStream), null);
        }
        
        static {
            stdHeaders = new String[] { "Content-Type", "Content-Disposition", "Content-Transfer-Encoding", "Content-Description" };
            stdValues = new String[] { "application/pkcs7-mime; name=\"smime.p7m\"; smime-type=enveloped-data", "attachment; filename=\"smime.p7m\"", "base64", "S/MIME Encrypted Message" };
        }
    }
    
    private static class ContentOutputStream extends OutputStream
    {
        private final OutputStream main;
        private final OutputStream backing;
        
        ContentOutputStream(final OutputStream main, final OutputStream backing) {
            this.main = main;
            this.backing = backing;
        }
        
        @Override
        public void write(final byte[] b) throws IOException {
            this.main.write(b);
        }
        
        @Override
        public void write(final byte[] b, final int off, final int len) throws IOException {
            this.main.write(b, off, len);
        }
        
        @Override
        public void write(final int n) throws IOException {
            this.main.write(n);
        }
        
        @Override
        public void close() throws IOException {
            this.main.close();
            if (this.backing != null) {
                this.backing.close();
            }
        }
    }
}
