/*
 * 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.commons.imaging.util;

import java.io.UnsupportedEncodingException;

import org.apache.commons.imaging.common.BinaryConstants;

public abstract class UnicodeUtils implements BinaryConstants
{
    /**
     * This class should never be instantiated.
     */
    private UnicodeUtils()
    {
    }

    public static class UnicodeException extends Exception
    {
        public UnicodeException(String message)
        {
            super(message);
        }
    }

    // A default single-byte charset.
    public static final int CHAR_ENCODING_CODE_ISO_8859_1 = 0;
    public static final int CHAR_ENCODING_CODE_UTF_16_BIG_ENDIAN_WITH_BOM = 1;
    public static final int CHAR_ENCODING_CODE_UTF_16_LITTLE_ENDIAN_WITH_BOM = 2;
    public static final int CHAR_ENCODING_CODE_UTF_16_BIG_ENDIAN_NO_BOM = 3;
    public static final int CHAR_ENCODING_CODE_UTF_16_LITTLE_ENDIAN_NO_BOM = 4;
    public static final int CHAR_ENCODING_CODE_UTF_8 = 5;
    public static final int CHAR_ENCODING_CODE_AMBIGUOUS = -1;

    // /*
    // * Guess the character encoding of arbitrary character data in a data
    // * buffer.
    // *
    // * The data may not run to the end of the buffer; it may be terminated.
    // This
    // * makes the problem much harder, since the character data may be followed
    // * by arbitrary data.
    // */
    // public static int guessCharacterEncoding(byte bytes[], int index)
    // {
    // int length = bytes.length - index;
    //
    // if (length < 1)
    // return CHAR_ENCODING_CODE_AMBIGUOUS;
    //
    // if (length >= 2)
    // {
    // // look for BOM.
    //
    // int c1 = 0xff & bytes[index];
    // int c2 = 0xff & bytes[index + 1];
    // if (c1 == 0xFF && c2 == 0xFE)
    // return CHAR_ENCODING_CODE_UTF_16_LITTLE_ENDIAN_WITH_BOM;
    // else if (c1 == 0xFE && c2 == 0xFF)
    // return CHAR_ENCODING_CODE_UTF_16_BIG_ENDIAN_WITH_BOM;
    // }
    //
    // }
    //
    // /*
    // * Guess the character encoding of arbitrary character data in a data
    // * buffer.
    // *
    // * The data fills the entire buffer. If it is terminated, the terminator
    // * byte(s) will be the last bytes in the buffer.
    // *
    // * This makes the problem a bit easier.
    // */
    // public static int guessCharacterEncodingSimple(byte bytes[], int index)
    // throws UnicodeException
    // {
    // int length = bytes.length - index;
    //
    // if (length < 1)
    // return CHAR_ENCODING_CODE_AMBIGUOUS;
    //
    // if (length >= 2)
    // {
    // // identify or eliminate UTF-16 with a BOM.
    //
    // int c1 = 0xff & bytes[index];
    // int c2 = 0xff & bytes[index + 1];
    // if (c1 == 0xFF && c2 == 0xFE)
    // return CHAR_ENCODING_CODE_UTF_16_LITTLE_ENDIAN_WITH_BOM;
    // else if (c1 == 0xFE && c2 == 0xFF)
    // return CHAR_ENCODING_CODE_UTF_16_BIG_ENDIAN_WITH_BOM;
    // }
    //
    // if (length >= 2)
    // {
    // // look for optional double-byte terminator.
    //
    // int c1 = 0xff & bytes[bytes.length - 2];
    // int c2 = 0xff & bytes[bytes.length - 1];
    // if (c1 == 0 && c2 == 0)
    // {
    // // definitely a flavor of UTF-16.
    // if (length % 2 != 0)
    // throw new UnicodeException(
    // "Character data with double-byte terminator has an odd length.");
    //
    // boolean mayHaveTerminator = true;
    // boolean mustHaveTerminator = false;
    // boolean possibleBigEndian = new UnicodeMetricsUTF16NoBOM(
    // BYTE_ORDER_BIG_ENDIAN).isValid(bytes, index,
    // mayHaveTerminator, mustHaveTerminator);
    // boolean possibleLittleEndian = new UnicodeMetricsUTF16NoBOM(
    // BYTE_ORDER_LITTLE_ENDIAN).isValid(bytes, index,
    // mayHaveTerminator, mustHaveTerminator);
    // if ((!possibleBigEndian) && (!possibleLittleEndian))
    // throw new UnicodeException(
    // "Invalid character data, possibly UTF-16.");
    // if (possibleBigEndian && possibleLittleEndian)
    // return CHAR_ENCODING_CODE_AMBIGUOUS;
    // if (possibleBigEndian)
    // return CHAR_ENCODING_CODE_UTF_16_BIG_ENDIAN_NO_BOM;
    // if (possibleLittleEndian)
    // return CHAR_ENCODING_CODE_UTF_16_LITTLE_ENDIAN_NO_BOM;
    // }
    // }
    //
    // List possibleEncodings = new ArrayList();
    // if (length % 2 == 0)
    // {
    // boolean mayHaveTerminator = true;
    // boolean mustHaveTerminator = false;
    // boolean possibleBigEndian = new UnicodeMetricsUTF16NoBOM(
    // BYTE_ORDER_BIG_ENDIAN).isValid(bytes, index,
    // mayHaveTerminator, mustHaveTerminator);
    // boolean possibleLittleEndian = new UnicodeMetricsUTF16NoBOM(
    // BYTE_ORDER_LITTLE_ENDIAN).isValid(bytes, index,
    // mayHaveTerminator, mustHaveTerminator);
    //
    // if (possibleBigEndian)
    // return CHAR_ENCODING_CODE_UTF_16_BIG_ENDIAN_NO_BOM;
    // if (possibleLittleEndian)
    // return CHAR_ENCODING_CODE_UTF_16_LITTLE_ENDIAN_NO_BOM;
    // }
    //
    // }

    public static final boolean isValidISO_8859_1(String s)
    {
        try
        {
            String roundtrip = new String(s.getBytes("ISO-8859-1"),
                    "ISO-8859-1");
            return s.equals(roundtrip);
        } catch (UnsupportedEncodingException e)
        {
            // should never be thrown.
            throw new RuntimeException("Error parsing string.", e);
        }
    }

    /*
     * Return the index of the first utf-16 terminator (ie. two even-aligned
     * nulls). If not found, return -1.
     */
    private static int findFirstDoubleByteTerminator(byte bytes[], int index)
    {
        for (int i = index; i < bytes.length - 1; i += 2)
        {
            int c1 = 0xff & bytes[index];
            int c2 = 0xff & bytes[index + 1];
            if (c1 == 0 && c2 == 0)
                return i;
        }
        return -1;
    }

    public final int findEndWithTerminator(byte bytes[], int index)
            throws UnicodeException
    {
        return findEnd(bytes, index, true);
    }

    public final int findEndWithoutTerminator(byte bytes[], int index)
            throws UnicodeException
    {
        return findEnd(bytes, index, false);
    }

    protected abstract int findEnd(byte bytes[], int index,
            boolean includeTerminator) throws UnicodeException;

    public static UnicodeUtils getInstance(int charEncodingCode)
            throws UnicodeException
    {
        switch (charEncodingCode)
        {
        case CHAR_ENCODING_CODE_ISO_8859_1:
            return new UnicodeMetricsASCII();
        case CHAR_ENCODING_CODE_UTF_8:
            // Debug.debug("CHAR_ENCODING_CODE_UTF_8");
            return new UnicodeMetricsUTF8();
        case CHAR_ENCODING_CODE_UTF_16_BIG_ENDIAN_WITH_BOM:
        case CHAR_ENCODING_CODE_UTF_16_LITTLE_ENDIAN_WITH_BOM:
            // Debug.debug("CHAR_ENCODING_CODE_UTF_16_WITH_BOM");
            return new UnicodeMetricsUTF16WithBOM();
        case CHAR_ENCODING_CODE_UTF_16_BIG_ENDIAN_NO_BOM:
            return new UnicodeMetricsUTF16NoBOM(BYTE_ORDER_BIG_ENDIAN);
        case CHAR_ENCODING_CODE_UTF_16_LITTLE_ENDIAN_NO_BOM:
            return new UnicodeMetricsUTF16NoBOM(BYTE_ORDER_LITTLE_ENDIAN);
        default:
            throw new UnicodeException("Unknown char encoding code: "
                    + charEncodingCode);
        }
    }

    private static class UnicodeMetricsASCII extends UnicodeUtils
    {
        @Override
        public int findEnd(byte bytes[], int index, boolean includeTerminator)
                throws UnicodeException
        {
            for (int i = index; i < bytes.length; i++)
            {
                if (bytes[i] == 0)
                    return includeTerminator ? i + 1 : i;
            }
            return bytes.length;
            // throw new UnicodeException("Terminator not found.");
        }
    }

    // private static class UnicodeMetricsISO_8859_1 extends UnicodeUtils
    // {
    // public int findEnd(byte bytes[], int index, boolean includeTerminator)
    // throws UnicodeException
    // {
    // for (int i = index; i < bytes.length; i++)
    // {
    // if (bytes[i] == 0)
    // return includeTerminator ? i + 1 : i;
    // }
    // return bytes.length;
    // // throw new UnicodeException("Terminator not found.");
    // }
    // }

    private static class UnicodeMetricsUTF8 extends UnicodeUtils
    {

        @Override
        public int findEnd(byte bytes[], int index, boolean includeTerminator)
                throws UnicodeException
        {
            // http://en.wikipedia.org/wiki/UTF-8

            while (true)
            {
                if (index == bytes.length)
                    return bytes.length;
                if (index > bytes.length)
                    throw new UnicodeException("Terminator not found.");

                int c1 = 0xff & bytes[index++];
                if (c1 == 0)
                    return includeTerminator ? index : index - 1;
                else if (c1 <= 0x7f)
                    continue;
                else if (c1 <= 0xDF)
                {
                    if (index >= bytes.length)
                        throw new UnicodeException("Invalid unicode.");

                    int c2 = 0xff & bytes[index++];
                    if (c2 < 0x80 || c2 > 0xBF)
                        throw new UnicodeException("Invalid code point.");
                } else if (c1 <= 0xEF)
                {
                    if (index >= bytes.length - 1)
                        throw new UnicodeException("Invalid unicode.");

                    int c2 = 0xff & bytes[index++];
                    if (c2 < 0x80 || c2 > 0xBF)
                        throw new UnicodeException("Invalid code point.");
                    int c3 = 0xff & bytes[index++];
                    if (c3 < 0x80 || c3 > 0xBF)
                        throw new UnicodeException("Invalid code point.");
                } else if (c1 <= 0xF4)
                {
                    if (index >= bytes.length - 2)
                        throw new UnicodeException("Invalid unicode.");

                    int c2 = 0xff & bytes[index++];
                    if (c2 < 0x80 || c2 > 0xBF)
                        throw new UnicodeException("Invalid code point.");
                    int c3 = 0xff & bytes[index++];
                    if (c3 < 0x80 || c3 > 0xBF)
                        throw new UnicodeException("Invalid code point.");
                    int c4 = 0xff & bytes[index++];
                    if (c4 < 0x80 || c4 > 0xBF)
                        throw new UnicodeException("Invalid code point.");
                } else
                    throw new UnicodeException("Invalid code point.");
            }
        }
    }

    private abstract static class UnicodeMetricsUTF16 extends UnicodeUtils
    {
        protected int byteOrder = BYTE_ORDER_BIG_ENDIAN;

        public UnicodeMetricsUTF16(int byteOrder)
        {
            this.byteOrder = byteOrder;
        }

        public boolean isValid(byte bytes[], int index,
                boolean mayHaveTerminator, boolean mustHaveTerminator)
        {
            // http://en.wikipedia.org/wiki/UTF-16/UCS-2

            while (true)
            {
                if (index == bytes.length)
                {
                    // end of buffer, no terminator found.
                    return !mustHaveTerminator;
                }

                if (index >= bytes.length - 1)
                {
                    // end of odd-length buffer, no terminator found.
                    return false;
                }

                int c1 = 0xff & bytes[index++];
                int c2 = 0xff & bytes[index++];
                int msb1 = byteOrder == BYTE_ORDER_BIG_ENDIAN ? c1 : c2;

                if (c1 == 0 && c2 == 0)
                {
                    // terminator found.
                    return mayHaveTerminator;
                }

                if (msb1 >= 0xD8)
                {
                    // Surrogate pair found.

                    if (msb1 >= 0xDC)
                    {
                        // invalid first surrogate.
                        return false;
                    }

                    if (index >= bytes.length - 1)
                    {
                        // missing second surrogate.
                        return false;
                    }

                    // second word.
                    int c3 = 0xff & bytes[index++];
                    int c4 = 0xff & bytes[index++];
                    int msb2 = byteOrder == BYTE_ORDER_BIG_ENDIAN ? c3 : c4;
                    if (msb2 < 0xDC)
                    {
                        // invalid second surrogate.
                        return false;
                    }
                }
            }
        }

        @Override
        public int findEnd(byte bytes[], int index, boolean includeTerminator)
                throws UnicodeException
        {
            // http://en.wikipedia.org/wiki/UTF-16/UCS-2

            while (true)
            {
                if (index == bytes.length)
                    return bytes.length;
                if (index > bytes.length - 1)
                    throw new UnicodeException("Terminator not found.");

                int c1 = 0xff & bytes[index++];
                int c2 = 0xff & bytes[index++];
                int msb1 = byteOrder == BYTE_ORDER_BIG_ENDIAN ? c1 : c2;

                if (c1 == 0 && c2 == 0)
                {
                    return includeTerminator ? index : index - 2;
                } else if (msb1 >= 0xD8)
                {
                    if (index > bytes.length - 1)
                        throw new UnicodeException("Terminator not found.");

                    // second word.
                    int c3 = 0xff & bytes[index++];
                    int c4 = 0xff & bytes[index++];
                    int msb2 = byteOrder == BYTE_ORDER_BIG_ENDIAN ? c3 : c4;
                    if (msb2 < 0xDC)
                        throw new UnicodeException("Invalid code point.");
                }
            }
        }
    }

    private static class UnicodeMetricsUTF16NoBOM extends UnicodeMetricsUTF16
    {

        public UnicodeMetricsUTF16NoBOM(final int byteOrder)
        {
            super(byteOrder);
        }

    }

    private static class UnicodeMetricsUTF16WithBOM extends UnicodeMetricsUTF16
    {

        public UnicodeMetricsUTF16WithBOM()
        {
            super(BYTE_ORDER_BIG_ENDIAN);
        }

        @Override
        public int findEnd(byte bytes[], int index, boolean includeTerminator)
                throws UnicodeException
        {
            // http://en.wikipedia.org/wiki/UTF-16/UCS-2

            if (index >= bytes.length - 1)
                throw new UnicodeException("Missing BOM.");

            int c1 = 0xff & bytes[index++];
            int c2 = 0xff & bytes[index++];
            if (c1 == 0xFF && c2 == 0xFE)
                byteOrder = BYTE_ORDER_LITTLE_ENDIAN;
            else if (c1 == 0xFE && c2 == 0xFF)
                byteOrder = BYTE_ORDER_BIG_ENDIAN;
            else
                throw new UnicodeException("Invalid byte order mark.");

            return super.findEnd(bytes, index, includeTerminator);
        }
    }

}
