package org.bouncycastle.mime.smime;

import java.io.IOException;
import java.io.OutputStream;
import java.util.LinkedHashMap;
import java.util.Map;

import org.bouncycastle.cms.CMSAttributeTableGenerator;
import org.bouncycastle.cms.CMSEnvelopedDataStreamGenerator;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.OriginatorInformation;
import org.bouncycastle.cms.RecipientInfoGenerator;
import org.bouncycastle.mime.Headers;
import org.bouncycastle.mime.MimeIOException;
import org.bouncycastle.mime.MimeWriter;
import org.bouncycastle.mime.encoding.Base64OutputStream;
import org.bouncycastle.operator.OutputEncryptor;
import org.bouncycastle.util.Strings;

/**
 * Writer for SMIME Enveloped objects.
 */
public class SMIMEEnvelopedWriter
    extends MimeWriter
{
    public static class Builder
    {
        private static final String[] stdHeaders;
        private static final String[] stdValues;

        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 final CMSEnvelopedDataStreamGenerator envGen = new CMSEnvelopedDataStreamGenerator();
        private final Map<String, String> headers = new LinkedHashMap<String, String>();

        String contentTransferEncoding = "base64";

        public Builder()
        {
            for (int i = 0; i != stdHeaders.length; i++)
            {
                headers.put(stdHeaders[i], stdValues[i]);
            }
        }

        public Builder setUnprotectedAttributeGenerator(CMSAttributeTableGenerator unprotectedAttributeGenerator)
        {
            this.envGen.setUnprotectedAttributeGenerator(unprotectedAttributeGenerator);

            return this;
        }

        public Builder setOriginatorInfo(OriginatorInformation originatorInfo)
        {
            this.envGen.setOriginatorInfo(originatorInfo);

            return this;
        }

        /**
         * Specify a MIME header (name, value) pair for this builder. If the headerName already exists it will
         * be overridden.
         *
         * @param headerName name of the MIME header.
         * @param headerValue value of the MIME header.
         *
         * @return the current Builder instance.
         */
        public Builder withHeader(String headerName, String headerValue)
        {
            this.headers.put(headerName, headerValue);

            return this;
        }
        
        /**
         * Add a generator to produce the recipient info required.
         *
         * @param recipientGenerator a generator of a recipient info object.
         *
         * @return the current Builder instance.
         */
        public Builder addRecipientInfoGenerator(RecipientInfoGenerator recipientGenerator)
        {
            this.envGen.addRecipientInfoGenerator(recipientGenerator);

            return this;
        }

        public SMIMEEnvelopedWriter build(OutputStream mimeOut, OutputEncryptor outEnc)
        {
            return new SMIMEEnvelopedWriter(this, outEnc, mimeOut);
        }
    }

    private final CMSEnvelopedDataStreamGenerator envGen;

    private final OutputEncryptor outEnc;
    private final OutputStream mimeOut;
    private final String contentTransferEncoding;

    private SMIMEEnvelopedWriter(Builder builder, OutputEncryptor outEnc, OutputStream mimeOut)
    {
        super(new Headers(mapToLines(builder.headers), builder.contentTransferEncoding));

        this.envGen = builder.envGen;
        this.contentTransferEncoding = builder.contentTransferEncoding;
        this.outEnc = outEnc;
        this.mimeOut = mimeOut;
    }
    
    public OutputStream getContentStream()
        throws IOException
    {
        headers.dumpHeaders(mimeOut);

        mimeOut.write(Strings.toByteArray("\r\n"));

        try
        {
            OutputStream outStream;

            if ("base64".equals(contentTransferEncoding))
            {
                outStream = new Base64OutputStream(mimeOut);
                
                return new ContentOutputStream(envGen.open(SMimeUtils.createUnclosable(outStream), outEnc), outStream);
            }
            else
            {
                return new ContentOutputStream(envGen.open(SMimeUtils.createUnclosable(mimeOut), outEnc), null);
            }
        }
        catch (CMSException e)
        {
            throw new MimeIOException(e.getMessage(), e);
        }
    }

    private class ContentOutputStream
        extends OutputStream
    {
        private final OutputStream main;
        private final OutputStream backing;

        ContentOutputStream(OutputStream main, OutputStream backing)
        {
            this.main = main;
            this.backing = backing;
        }

        public void write(int i)
            throws IOException
        {
            main.write(i);
        }

        public void close()
            throws IOException
        {
            main.close();
            if (backing != null)
            {
                backing.close();
            }
        }
    }
}
