/**
 * 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.cxf.common.util;

/**
 * Base64Utility - this static class provides useful base64
 *                 encoding utilities.
 */

// Java imports
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.logging.Logger;

import org.apache.cxf.common.i18n.Message;
import org.apache.cxf.common.logging.LogUtils;


/**
 * This class converts to/from base64. The alternative conversions include:
 *
 * encode:
 *    byte[]     into String
 *    byte[]     into char[]
 *    byte[]     into OutStream
 *    byte[]     into Writer
 * decode:
 *    char[]     into byte[]
 *    String     into byte[]
 *    char[]     into OutStream
 *    String     into OutStream
 *
 */
public final class Base64Utility {

    private static final Logger LOG = LogUtils.getL7dLogger(Base64Utility.class);


    // base 64 character set
    //
    private static final char[] BCS = {
        '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', '+', '/'
    };

    private static final char[] BCS_URL_SAFE = Arrays.copyOf(BCS, BCS.length);

    // base 64 padding
    private static final char PAD = '=';

    // size of base 64 decode table
    private static final int BDTSIZE = 128;

    // base 64 decode table
    private static final byte[] BDT = new byte[128];


    private static final int PAD_SIZE0 = 1;
    private static final int PAD_SIZE4 = 2;
    private static final int PAD_SIZE8 = 3;

    // class static initializer for building decode table
    static {
        for (int i = 0;  i < BDTSIZE;  i++) {
            BDT[i] = Byte.MAX_VALUE;
        }

        for (int i = 0;  i < BCS.length;  i++) {
            BDT[BCS[i]] = (byte)i;
        }

        BCS_URL_SAFE[62] = '-';
        BCS_URL_SAFE[63] = '_';
    }


    private Base64Utility() {
        //utility class, never constructed
    }



    /**
     * The <code>decode_chunk</code> routine decodes a chunk of data
     * into its native encoding.
     *
     * base64 encodes each 3 octets of data into 4 characters from a
     * limited 64 character set. The 3 octets are joined to form
     * 24 bits which are then split into 4 x 6bit values. Each 6 bit
     * value is then used as an index into the 64 character table of
     * base64 chars. If the total data length is not a 3 octet multiple
     * the '=' char is used as padding for the final 4 char group,
     * either 1 octet + '==' or 2 octets + '='.
     *
     * @param   id  The input data to be processed
     * @param   o   The offset from which to begin processing
     * @param   l   The length (bound) at which processing is to end
     * @return  The decoded data
     * @exception   Base64Exception Thrown is processing fails due to
     * formatting exceptions in the encoded data
     */
    public static byte[] decodeChunk(char[] id,
                                     int o,
                                     int l)
        throws Base64Exception {

        if (id != null && id.length == 0 && l == 0) {
            return new byte[0];
        }

        // Keep it simple - must be >= 4. Unpadded
        // base64 data contain < 3 octets is invalid.
        //
        if ((l - o) < 4) {
            return null;
        }

        char[] ib = new char[4];
        int ibcount = 0;

        // cryan. Calc the num of octets. Each 4 chars of base64 chars
        // (representing 24 bits) encodes 3 octets.
        //
        int octetCount = 3 * (l / 4);

        // Final 4 chars may contain 3 octets or padded to contain
        // 1 or 2 octets.
        //
        if (id[l - 1] == PAD) {
            // TT== means last 4 chars encode 8 bits (ie subtract 2)
            // TTT= means last 4 chars encode 16 bits (ie subtract 1)
            octetCount -= (id[l - 2] == PAD) ? 2 : 1;
        }

        byte[] ob = new byte[octetCount];
        int obcount = 0;

        for (int i = o;  i < o + l && i < id.length;  i++) {
            if (id[i] == PAD
                || id[i] < BDT.length
                && BDT[id[i]] != Byte.MAX_VALUE) {

                ib[ibcount++] = id[i];

                // Decode each 4 char sequence.
                //
                if (ibcount == ib.length) {
                    ibcount = 0;
                    obcount += processEncodeme(ib, ob, obcount);
                }
            }
        }

        if (obcount != ob.length) {
            byte []tmp = new byte[obcount];
            System.arraycopy(ob, 0, tmp, 0, obcount);
            ob = tmp;
        }

        return ob;
    }

    public static byte[] decode(String id) throws Base64Exception {
        return decode(id, false);
    }

    public static byte[] decode(String id, boolean urlSafe) throws Base64Exception {
        if (urlSafe) {
            id = id.replace('-', '+').replace('_', '/');
            switch (id.length() % 4) {
            case 0:
                break;
            case 2:
                id += "==";
                break;
            case 3:
                id += "=";
                break;
            default:
                throw new Base64Exception(new Message("BASE64_RUNTIME_EXCEPTION", LOG));
            }
        }
        try {
            char[] cd = id.toCharArray();
            return decodeChunk(cd, 0, cd.length);
        } catch (Exception e) {
            LOG.warning("Invalid base64 encoded string : " + id);
            throw new Base64Exception(new Message("BASE64_RUNTIME_EXCEPTION", LOG), e);
        }
    }

    public static void decode(char[] id,
                             int o,
                             int l,
                             OutputStream ostream)
        throws Base64Exception {

        try {
            ostream.write(decodeChunk(id, o, l));
        } catch (Exception e) {
            LOG.warning("Invalid base64 encoded string : " + new String(id));
            throw new Base64Exception(new Message("BASE64_RUNTIME_EXCEPTION", LOG), e);
        }
    }

    public static void decode(String id,
                              OutputStream ostream)
        throws Base64Exception {

        try {
            char[] cd = id.toCharArray();
            ostream.write(decodeChunk(cd, 0, cd.length));
        } catch (IOException ioe) {
            throw new Base64Exception(new Message("BASE64_DECODE_IOEXCEPTION", LOG), ioe);
        } catch (Exception e) {
            LOG.warning("Invalid base64 encoded string : " + id);
            throw new Base64Exception(new Message("BASE64_RUNTIME_EXCEPTION", LOG), e);
        }
    }

    // Returns base64 representation of specified byte array.
    //
    public static String encode(byte[] id) {
        return encode(id, false);
    }

    public static String encode(byte[] id, boolean urlSafe) {
        char[] cd = encodeChunk(id, 0, id.length);
        return new String(cd, 0, cd.length);
    }

    // Returns base64 representation of specified byte array.
    //
    public static char[] encodeChunk(byte[] id,
                                     int o,
                                     int l) {
        return encodeChunk(id, o, l, false);
    }

    public static char[] encodeChunk(byte[] id,
                                     int o,
                                     int l,
                                     boolean urlSafe) {
        if (id != null && id.length == 0 && l == 0) {
            return new char[0];
        } else if (l <= 0) {
            return null;
        }

        char[] out;

        // If not a multiple of 3 octets then a final padded 4 char
        // slot is needed.
        //
        if (l % 3 == 0) {
            out = new char[l / 3 * 4];
        } else {
            int finalLen = !urlSafe ? 4 : l % 3 == 1 ? 2 : 3;
            out = new char[l / 3 * 4 + finalLen];
        }

        int rindex = o;
        int windex = 0;
        int rest = l;

        final char[] base64Table = urlSafe ? BCS_URL_SAFE : BCS;
        while (rest >= 3) {
            int i = ((id[rindex] & 0xff) << 16)
                    + ((id[rindex + 1] & 0xff) << 8)
                    + (id[rindex + 2] & 0xff);

            out[windex++] = base64Table[i >> 18];
            out[windex++] = base64Table[(i >> 12) & 0x3f];
            out[windex++] = base64Table[(i >> 6) & 0x3f];
            out[windex++] = base64Table[i & 0x3f];
            rindex += 3;
            rest -= 3;
        }

        if (rest == 1) {
            int i = id[rindex] & 0xff;
            out[windex++] = base64Table[i >> 2];
            out[windex++] = base64Table[(i << 4) & 0x3f];
            if (!urlSafe) {
                out[windex++] = PAD;
                out[windex] = PAD;
            }
        } else if (rest == 2) {
            int i = ((id[rindex] & 0xff) << 8) + (id[rindex + 1] & 0xff);
            out[windex++] = base64Table[i >> 10];
            out[windex++] = base64Table[(i >> 4) & 0x3f];
            out[windex++] = base64Table[(i << 2) & 0x3f];
            if (!urlSafe) {
                out[windex] = PAD;
            }
        }
        return out;
    }

    public static void encodeAndStream(byte[] id,
                                       int o,
                                       int l,
                                       OutputStream os) throws IOException {
        encodeAndStream(id, o, l, false, os);
    }

    public static void encodeAndStream(byte[] id,
                                           int o,
                                           int l,
                                           boolean urlSafe,
                                           OutputStream os) throws IOException {
        if (l <= 0) {
            return;
        }

        int rindex = o;
        int rest = l;
        final char[] base64Table = urlSafe ? BCS_URL_SAFE : BCS;

        char[] chunk = new char[4];
        while (rest >= 3) {
            int i = ((id[rindex] & 0xff) << 16)
                    + ((id[rindex + 1] & 0xff) << 8)
                    + (id[rindex + 2] & 0xff);
            chunk[0] = base64Table[i >> 18];
            chunk[1] = base64Table[(i >> 12) & 0x3f];
            chunk[2] = base64Table[(i >> 6) & 0x3f];
            chunk[3] = base64Table[i & 0x3f];
            writeCharArrayToStream(chunk, 4, os);
            rindex += 3;
            rest -= 3;
        }
        if (rest == 0) {
            return;
        }
        if (rest == 1) {
            int i = id[rindex] & 0xff;
            chunk[0] = base64Table[i >> 2];
            chunk[1] = base64Table[(i << 4) & 0x3f];
            if (!urlSafe) {
                chunk[2] = PAD;
                chunk[3] = PAD;
            }
        } else if (rest == 2) {
            int i = ((id[rindex] & 0xff) << 8) + (id[rindex + 1] & 0xff);
            chunk[0] = base64Table[i >> 10];
            chunk[1] = base64Table[(i >> 4) & 0x3f];
            chunk[2] = base64Table[(i << 2) & 0x3f];
            if (!urlSafe) {
                chunk[3] = PAD;
            }
        }
        int finalLenToWrite = !urlSafe ? 4 : rest == 1 ? 2 : 3;
        writeCharArrayToStream(chunk, finalLenToWrite, os);
    }

    private static void writeCharArrayToStream(char[] chunk, int len, OutputStream os) throws IOException {
        // may be we can just cast to byte when creating chunk[] earlier on
        byte[] bytes = StandardCharsets.UTF_8.encode(CharBuffer.wrap(chunk, 0, len)).array();
        os.write(bytes);
    }

    //
    // Outputs base64 representation of the specified byte array
    // to a byte stream.
    //
    public static void encodeChunk(byte[] id,
                                   int o,
                                   int l,
                                   OutputStream ostream) throws Base64Exception {
        try {
            ostream.write(new String(encodeChunk(id, o, l)).getBytes());
        } catch (IOException e) {
            throw new Base64Exception(new Message("BASE64_ENCODE_IOEXCEPTION", LOG), e);
        }
    }

    // Outputs base64 representation of the specified byte
    // array to a character stream.
    //
    public static void encode(byte[] id,
                              int o,
                              int l,
                              Writer writer) throws Base64Exception {
        try {
            writer.write(encodeChunk(id, o, l));
        } catch (IOException e) {
            throw new Base64Exception(new Message("BASE64_ENCODE_WRITER_IOEXCEPTION", LOG), e);
        }
    }
    //---- Private static methods --------------------------------------

    /**
     * The <code>process</code> routine processes an atomic base64
     * unit of encoding (encodeme) into its native encoding. This class is
     * used by decode routines to do the grunt work of decoding
     * base64 encoded information
     *
     * @param   ib  Input character buffer of encoded bytes
     * @param   ob  Output byte buffer of decoded bytes
     * @param   p   Pointer to the encodeme of interest
     * @return  The decoded encodeme
     * @exception   Base64Exception Thrown is processing fails due to
     * formatting exceptions in the encoded data
     */
    private static int processEncodeme(char[] ib,
                                       byte[] ob,
                                       int p)
        throws Base64Exception {


        int spad = PAD_SIZE8;
        if (ib[3] == PAD) {
            spad = PAD_SIZE4;
        }
        if (ib[2] == PAD) {
            spad = PAD_SIZE0;
        }

        int b0 = BDT[ib[0]];
        int b1 = BDT[ib[1]];
        int b2 = BDT[ib[2]];
        int b3 = BDT[ib[3]];

        switch (spad) {
        case PAD_SIZE0:
            ob[p] = (byte)(b0 << 2 & 0xfc | b1 >> 4 & 0x3);
            return PAD_SIZE0;
        case PAD_SIZE4:
            ob[p++] = (byte)(b0 << 2 & 0xfc | b1 >> 4 & 0x3);
            ob[p] = (byte)(b1 << 4 & 0xf0 | b2 >> 2 & 0xf);
            return PAD_SIZE4;
        case PAD_SIZE8:
            ob[p++] = (byte)(b0 << 2 & 0xfc | b1 >> 4 & 0x3);
            ob[p++] = (byte)(b1 << 4 & 0xf0 | b2 >> 2 & 0xf);
            ob[p] = (byte)(b2 << 6 & 0xc0 | b3 & 0x3f);
            return PAD_SIZE8;
        default:
            // We should never get here
            throw new IllegalStateException();
        }
    }

    public static boolean isValidBase64(int ch) {
        return ch == PAD || BDT[ch] != Byte.MAX_VALUE;
    }

}
