/****************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one   *
 * or more contributor license agreements.  See the NOTICE file *
 * distributed with this work for additional information        *
 * regarding copyright ownership.  The ASF licenses this file   *
 * to you under the Apache License, Version 2.0 (the            *
 * "License"); you may not use this file except in compliance   *
 * with the License.  You may obtain a copy of the License at   *
 *                                                              *
 *   http://www.apache.org/licenses/LICENSE-2.0                 *
 *                                                              *
 * Unless required by applicable law or agreed to in writing,   *
 * software distributed under the License is distributed on an  *
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
 * KIND, either express or implied.  See the License for the    *
 * specific language governing permissions and limitations      *
 * under the License.                                           *
 ****************************************************************/

package org.apache.james.mime4j.codec;

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashSet;
import java.util.Set;

/**
 * This class implements section <cite>6.8. Base64 Content-Transfer-Encoding</cite>
 * from RFC 2045 <cite>Multipurpose Internet Mail Extensions (MIME) Part One:
 * Format of Internet Message Bodies</cite> by Freed and Borenstein.
 * <p>
 * Code is based on Base64 and Base64OutputStream code from Commons-Codec 1.4.
 * 
 * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
 */
public class Base64OutputStream extends FilterOutputStream {

    // Default line length per RFC 2045 section 6.8.
    private static final int DEFAULT_LINE_LENGTH = 76;

    // CRLF line separator per RFC 2045 section 2.1.
    private static final byte[] CRLF_SEPARATOR = { '\r', '\n' };

    // This array is a lookup table that translates 6-bit positive integer index
    // values into their "Base64 Alphabet" equivalents as specified in Table 1
    // of RFC 2045.
    static final byte[] BASE64_TABLE = { 'A', 'B', 'C', 'D', 'E', 'F',
            'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
            'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
            't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', '+', '/' };

    // Byte used to pad output.
    private static final byte BASE64_PAD = '=';

    // This set contains all base64 characters including the pad character. Used
    // solely to check if a line separator contains any of these characters.
    private static final Set<Byte> BASE64_CHARS = new HashSet<Byte>();

    static {
        for (byte b : BASE64_TABLE) {
            BASE64_CHARS.add(b);
        }
        BASE64_CHARS.add(BASE64_PAD);
    }

    // Mask used to extract 6 bits
    private static final int MASK_6BITS = 0x3f;

    private static final int ENCODED_BUFFER_SIZE = 2048;

    private final byte[] singleByte = new byte[1];

    private final int lineLength;
    private final byte[] lineSeparator;

    private boolean closed = false;

    private final byte[] encoded;
    private int position = 0;

    private int data = 0;
    private int modulus = 0;

    private int linePosition = 0;

    /**
     * Creates a <code>Base64OutputStream</code> that writes the encoded data
     * to the given output stream using the default line length (76) and line
     * separator (CRLF).
     * 
     * @param out
     *            underlying output stream.
     */
    public Base64OutputStream(OutputStream out) {
        this(out, DEFAULT_LINE_LENGTH, CRLF_SEPARATOR);
    }

    /**
     * Creates a <code>Base64OutputStream</code> that writes the encoded data
     * to the given output stream using the given line length and the default
     * line separator (CRLF).
     * <p>
     * The given line length will be rounded up to the nearest multiple of 4. If
     * the line length is zero then the output will not be split into lines.
     * 
     * @param out
     *            underlying output stream.
     * @param lineLength
     *            desired line length.
     */
    public Base64OutputStream(OutputStream out, int lineLength) {
        this(out, lineLength, CRLF_SEPARATOR);
    }

    /**
     * Creates a <code>Base64OutputStream</code> that writes the encoded data
     * to the given output stream using the given line length and line
     * separator.
     * <p>
     * The given line length will be rounded up to the nearest multiple of 4. If
     * the line length is zero then the output will not be split into lines and
     * the line separator is ignored.
     * <p>
     * The line separator must not include characters from the BASE64 alphabet
     * (including the padding character <code>=</code>).
     * 
     * @param out
     *            underlying output stream.
     * @param lineLength
     *            desired line length.
     * @param lineSeparator
     *            line separator to use.
     */
    public Base64OutputStream(OutputStream out, int lineLength,
            byte[] lineSeparator) {
        super(out);

        if (out == null)
            throw new IllegalArgumentException();
        if (lineLength < 0)
            throw new IllegalArgumentException();
        checkLineSeparator(lineSeparator);

        this.lineLength = lineLength;
        this.lineSeparator = new byte[lineSeparator.length];
        System.arraycopy(lineSeparator, 0, this.lineSeparator, 0,
                lineSeparator.length);

        this.encoded = new byte[ENCODED_BUFFER_SIZE];
    }

    @Override
    public final void write(final int b) throws IOException {
        if (closed)
            throw new IOException("Base64OutputStream has been closed");

        singleByte[0] = (byte) b;
        write0(singleByte, 0, 1);
    }

    @Override
    public final void write(final byte[] buffer) throws IOException {
        if (closed)
            throw new IOException("Base64OutputStream has been closed");

        if (buffer == null)
            throw new NullPointerException();

        if (buffer.length == 0)
            return;

        write0(buffer, 0, buffer.length);
    }

    @Override
    public final void write(final byte[] buffer, final int offset,
            final int length) throws IOException {
        if (closed)
            throw new IOException("Base64OutputStream has been closed");

        if (buffer == null)
            throw new NullPointerException();

        if (offset < 0 || length < 0 || offset + length > buffer.length)
            throw new IndexOutOfBoundsException();

        if (length == 0)
            return;

        write0(buffer, offset, offset + length);
    }

    @Override
    public void flush() throws IOException {
        if (closed)
            throw new IOException("Base64OutputStream has been closed");

        flush0();
    }

    @Override
    public void close() throws IOException {
        if (closed)
            return;

        closed = true;
        close0();
    }

    private void write0(final byte[] buffer, final int from, final int to)
            throws IOException {
        for (int i = from; i < to; i++) {
            data = (data << 8) | (buffer[i] & 0xff);

            if (++modulus == 3) {
                modulus = 0;

                // write line separator if necessary

                if (lineLength > 0 && linePosition >= lineLength) {
                    // writeLineSeparator() inlined for performance reasons

                    linePosition = 0;

                    if (encoded.length - position < lineSeparator.length)
                        flush0();

                    for (byte ls : lineSeparator)
                        encoded[position++] = ls;
                }

                // encode data into 4 bytes

                if (encoded.length - position < 4)
                    flush0();

                encoded[position++] = BASE64_TABLE[(data >> 18) & MASK_6BITS];
                encoded[position++] = BASE64_TABLE[(data >> 12) & MASK_6BITS];
                encoded[position++] = BASE64_TABLE[(data >> 6) & MASK_6BITS];
                encoded[position++] = BASE64_TABLE[data & MASK_6BITS];

                linePosition += 4;
            }
        }
    }

    private void flush0() throws IOException {
        if (position > 0) {
            out.write(encoded, 0, position);
            position = 0;
        }
    }

    private void close0() throws IOException {
        if (modulus != 0)
            writePad();

        // write line separator at the end of the encoded data

        if (lineLength > 0 && linePosition > 0) {
            writeLineSeparator();
        }

        flush0();
    }

    private void writePad() throws IOException {
        // write line separator if necessary

        if (lineLength > 0 && linePosition >= lineLength) {
            writeLineSeparator();
        }

        // encode data into 4 bytes

        if (encoded.length - position < 4)
            flush0();

        if (modulus == 1) {
            encoded[position++] = BASE64_TABLE[(data >> 2) & MASK_6BITS];
            encoded[position++] = BASE64_TABLE[(data << 4) & MASK_6BITS];
            encoded[position++] = BASE64_PAD;
            encoded[position++] = BASE64_PAD;
        } else {
            assert modulus == 2;
            encoded[position++] = BASE64_TABLE[(data >> 10) & MASK_6BITS];
            encoded[position++] = BASE64_TABLE[(data >> 4) & MASK_6BITS];
            encoded[position++] = BASE64_TABLE[(data << 2) & MASK_6BITS];
            encoded[position++] = BASE64_PAD;
        }

        linePosition += 4;
    }

    private void writeLineSeparator() throws IOException {
        linePosition = 0;

        if (encoded.length - position < lineSeparator.length)
            flush0();

        for (byte ls : lineSeparator)
            encoded[position++] = ls;
    }

    private void checkLineSeparator(byte[] lineSeparator) {
        if (lineSeparator.length > ENCODED_BUFFER_SIZE)
            throw new IllegalArgumentException("line separator length exceeds "
                    + ENCODED_BUFFER_SIZE);

        for (byte b : lineSeparator) {
            if (BASE64_CHARS.contains(b)) {
                throw new IllegalArgumentException(
                        "line separator must not contain base64 character '"
                                + (char) (b & 0xff) + "'");
            }
        }
    }
}
