// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 ****************************************************************************
 * Copyright (C) 2005-2012, International Business Machines Corporation and *
 * others. All Rights Reserved.                                             *
 ****************************************************************************
 *
 */
package com.ibm.icu.text;

import java.util.Arrays;

/**
 * CharsetRecognizer implemenation for Asian  - double or multi-byte - charsets.
 *                   Match is determined mostly by the input data adhering to the
 *                   encoding scheme for the charset, and, optionally,
 *                   frequency-of-occurence of characters.
 * <p/>
 *                   Instances of this class are singletons, one per encoding
 *                   being recognized.  They are created in the main
 *                   CharsetDetector class and kept in the global list of available
 *                   encodings to be checked.  The specific encoding being recognized
 *                   is determined by subclass.
 */
abstract class CharsetRecog_mbcs extends CharsetRecognizer {

   /**
     * Get the IANA name of this charset.
     * @return the charset name.
     */
    @Override
    abstract String      getName() ;


    /**
     * Test the match of this charset with the input text data
     *      which is obtained via the CharsetDetector object.
     *
     * @param det  The CharsetDetector, which contains the input text
     *             to be checked for being in this charset.
     * @return     Two values packed into one int  (Damn java, anyhow)
     *             <br/>
     *             bits 0-7:  the match confidence, ranging from 0-100
     *             <br/>
     *             bits 8-15: The match reason, an enum-like value.
     */
    int match(CharsetDetector det, int [] commonChars) {
        @SuppressWarnings("unused")
        int   singleByteCharCount = 0;  //TODO Do we really need this?
        int   doubleByteCharCount = 0;
        int   commonCharCount     = 0;
        int   badCharCount        = 0;
        int   totalCharCount      = 0;
        int   confidence          = 0;
        iteratedChar   iter       = new iteratedChar();

        detectBlock: {
            for (iter.reset(); nextChar(iter, det);) {
                totalCharCount++;
                if (iter.error) {
                    badCharCount++;
                } else {
                    long cv = iter.charValue & 0xFFFFFFFFL;

                    if (cv <= 0xff) {
                        singleByteCharCount++;
                    } else {
                        doubleByteCharCount++;
                        if (commonChars != null) {
                            // NOTE: This assumes that there are no 4-byte common chars.
                            if (Arrays.binarySearch(commonChars, (int) cv) >= 0) {
                                commonCharCount++;
                            }
                        }
                    }
                }
                if (badCharCount >= 2 && badCharCount*5 >= doubleByteCharCount) {
                    // Bail out early if the byte data is not matching the encoding scheme.
                    break detectBlock;
                }
            }

            if (doubleByteCharCount <= 10 && badCharCount== 0) {
                // Not many multi-byte chars.
                if (doubleByteCharCount == 0 && totalCharCount < 10) {
                    // There weren't any multibyte sequences, and there was a low density of non-ASCII single bytes.
                    // We don't have enough data to have any confidence.
                    // Statistical analysis of single byte non-ASCII charcters would probably help here.
                    confidence = 0;
                }
                else {
                    //   ASCII or ISO file?  It's probably not our encoding,
                    //   but is not incompatible with our encoding, so don't give it a zero.
                    confidence = 10;
                }

                break detectBlock;
            }

            //
            //  No match if there are too many characters that don't fit the encoding scheme.
            //    (should we have zero tolerance for these?)
            //
            if (doubleByteCharCount < 20*badCharCount) {
                confidence = 0;
                break detectBlock;
            }

            if (commonChars == null) {
                // We have no statistics on frequently occuring characters.
                //  Assess confidence purely on having a reasonable number of
                //  multi-byte characters (the more the better
                confidence = 30 + doubleByteCharCount - 20*badCharCount;
                if (confidence > 100) {
                    confidence = 100;
                }
            }else {
                //
                // Frequency of occurence statistics exist.
                //
                double maxVal = Math.log((float)doubleByteCharCount / 4);
                double scaleFactor = 90.0 / maxVal;
                confidence = (int)(Math.log(commonCharCount+1) * scaleFactor + 10);
                confidence = Math.min(confidence, 100);
            }
        }   // end of detectBlock:

        return confidence;
    }

     // "Character"  iterated character class.
     //    Recognizers for specific mbcs encodings make their "characters" available
     //    by providing a nextChar() function that fills in an instance of iteratedChar
     //    with the next char from the input.
     //    The returned characters are not converted to Unicode, but remain as the raw
     //    bytes (concatenated into an int) from the codepage data.
     //
     //  For Asian charsets, use the raw input rather than the input that has been
     //   stripped of markup.  Detection only considers multi-byte chars, effectively
     //   stripping markup anyway, and double byte chars do occur in markup too.
     //
     static class iteratedChar {
         int             charValue = 0;             // 1-4 bytes from the raw input data
         int             nextIndex = 0;
         boolean         error     = false;
         boolean         done      = false;

         void reset() {
             charValue = 0;
             nextIndex = 0;
             error     = false;
             done      = false;
         }

         int nextByte(CharsetDetector det) {
             if (nextIndex >= det.fRawLength) {
                 done = true;
                 return -1;
             }
             int byteValue = det.fRawInput[nextIndex++] & 0x00ff;
             return byteValue;
         }
     }

     /**
      * Get the next character (however many bytes it is) from the input data
      *    Subclasses for specific charset encodings must implement this function
      *    to get characters according to the rules of their encoding scheme.
      *
      *  This function is not a method of class iteratedChar only because
      *   that would require a lot of extra derived classes, which is awkward.
      * @param it  The iteratedChar "struct" into which the returned char is placed.
      * @param det The charset detector, which is needed to get at the input byte data
      *            being iterated over.
      * @return    True if a character was returned, false at end of input.
      */
     abstract boolean nextChar(iteratedChar it, CharsetDetector det);





     /**
      *   Shift-JIS charset recognizer.
      *
      */
     static class CharsetRecog_sjis extends CharsetRecog_mbcs {
         static int [] commonChars =
             // TODO:  This set of data comes from the character frequency-
             //        of-occurence analysis tool.  The data needs to be moved
             //        into a resource and loaded from there.
            {0x8140, 0x8141, 0x8142, 0x8145, 0x815b, 0x8169, 0x816a, 0x8175, 0x8176, 0x82a0,
             0x82a2, 0x82a4, 0x82a9, 0x82aa, 0x82ab, 0x82ad, 0x82af, 0x82b1, 0x82b3, 0x82b5,
             0x82b7, 0x82bd, 0x82be, 0x82c1, 0x82c4, 0x82c5, 0x82c6, 0x82c8, 0x82c9, 0x82cc,
             0x82cd, 0x82dc, 0x82e0, 0x82e7, 0x82e8, 0x82e9, 0x82ea, 0x82f0, 0x82f1, 0x8341,
             0x8343, 0x834e, 0x834f, 0x8358, 0x835e, 0x8362, 0x8367, 0x8375, 0x8376, 0x8389,
             0x838a, 0x838b, 0x838d, 0x8393, 0x8e96, 0x93fa, 0x95aa};

         @Override
        boolean nextChar(iteratedChar it, CharsetDetector det) {
             it.error = false;
             int firstByte;
             firstByte = it.charValue = it.nextByte(det);
             if (firstByte < 0) {
                 return false;
             }

             if (firstByte <= 0x7f || (firstByte>0xa0 && firstByte<=0xdf)) {
                 return true;
             }

             int secondByte = it.nextByte(det);
             if (secondByte < 0)  {
                 return false;
             }
             it.charValue = (firstByte << 8) | secondByte;
             if (! ((secondByte>=0x40 && secondByte<=0x7f) || (secondByte>=0x80 && secondByte<=0xff))) {
                 // Illegal second byte value.
                 it.error = true;
             }
             return true;
         }

         @Override
        CharsetMatch match(CharsetDetector det) {
             int confidence = match(det, commonChars);
             return confidence == 0 ? null : new CharsetMatch(det, this, confidence);
         }

         @Override
        String getName() {
             return "Shift_JIS";
         }

         @Override
        public String getLanguage()
         {
             return "ja";
         }


     }


     /**
      *   Big5 charset recognizer.
      *
      */
     static class CharsetRecog_big5 extends CharsetRecog_mbcs {
         static int [] commonChars =
             // TODO:  This set of data comes from the character frequency-
             //        of-occurence analysis tool.  The data needs to be moved
             //        into a resource and loaded from there.
            {0xa140, 0xa141, 0xa142, 0xa143, 0xa147, 0xa149, 0xa175, 0xa176, 0xa440, 0xa446,
             0xa447, 0xa448, 0xa451, 0xa454, 0xa457, 0xa464, 0xa46a, 0xa46c, 0xa477, 0xa4a3,
             0xa4a4, 0xa4a7, 0xa4c1, 0xa4ce, 0xa4d1, 0xa4df, 0xa4e8, 0xa4fd, 0xa540, 0xa548,
             0xa558, 0xa569, 0xa5cd, 0xa5e7, 0xa657, 0xa661, 0xa662, 0xa668, 0xa670, 0xa6a8,
             0xa6b3, 0xa6b9, 0xa6d3, 0xa6db, 0xa6e6, 0xa6f2, 0xa740, 0xa751, 0xa759, 0xa7da,
             0xa8a3, 0xa8a5, 0xa8ad, 0xa8d1, 0xa8d3, 0xa8e4, 0xa8fc, 0xa9c0, 0xa9d2, 0xa9f3,
             0xaa6b, 0xaaba, 0xaabe, 0xaacc, 0xaafc, 0xac47, 0xac4f, 0xacb0, 0xacd2, 0xad59,
             0xaec9, 0xafe0, 0xb0ea, 0xb16f, 0xb2b3, 0xb2c4, 0xb36f, 0xb44c, 0xb44e, 0xb54c,
             0xb5a5, 0xb5bd, 0xb5d0, 0xb5d8, 0xb671, 0xb7ed, 0xb867, 0xb944, 0xbad8, 0xbb44,
             0xbba1, 0xbdd1, 0xc2c4, 0xc3b9, 0xc440, 0xc45f};

         @Override
        boolean nextChar(iteratedChar it, CharsetDetector det) {
             it.error = false;
             int firstByte;
             firstByte = it.charValue = it.nextByte(det);
             if (firstByte < 0) {
                 return false;
             }

             if (firstByte <= 0x7f || firstByte==0xff) {
                 // single byte character.
                 return true;
             }

             int secondByte = it.nextByte(det);
             if (secondByte < 0)  {
                 return false;
             }
             it.charValue = (it.charValue << 8) | secondByte;

             if (secondByte < 0x40 ||
                 secondByte ==0x7f ||
                 secondByte == 0xff) {
                     it.error = true;
             }
             return true;
         }

         @Override
        CharsetMatch match(CharsetDetector det) {
             int confidence = match(det, commonChars);
             return confidence == 0 ? null : new CharsetMatch(det, this, confidence);
         }

         @Override
        String getName() {
             return "Big5";
         }


         @Override
        public String getLanguage()
         {
             return "zh";
         }
     }


     /**
      *   EUC charset recognizers.  One abstract class that provides the common function
      *             for getting the next character according to the EUC encoding scheme,
      *             and nested derived classes for EUC_KR, EUC_JP, EUC_CN.
      *
      */
     abstract static class CharsetRecog_euc extends CharsetRecog_mbcs {

         /*
          *  (non-Javadoc)
          *  Get the next character value for EUC based encodings.
          *  Character "value" is simply the raw bytes that make up the character
          *     packed into an int.
          */
         @Override
        boolean nextChar(iteratedChar it, CharsetDetector det) {
             it.error = false;
             int firstByte  = 0;
             int secondByte = 0;
             int thirdByte  = 0;
             //int fourthByte = 0;

             buildChar: {
                 firstByte = it.charValue = it.nextByte(det);
                 if (firstByte < 0) {
                     // Ran off the end of the input data
                     it.done = true;
                     break buildChar;
                 }
                 if (firstByte <= 0x8d) {
                     // single byte char
                     break buildChar;
                 }

                 secondByte = it.nextByte(det);
                 it.charValue = (it.charValue << 8) | secondByte;

                 if (firstByte >= 0xA1 && firstByte <= 0xfe) {
                     // Two byte Char
                     if (secondByte < 0xa1) {
                         it.error = true;
                     }
                     break buildChar;
                 }
                 if (firstByte == 0x8e) {
                     // Code Set 2.
                     //   In EUC-JP, total char size is 2 bytes, only one byte of actual char value.
                     //   In EUC-TW, total char size is 4 bytes, three bytes contribute to char value.
                     // We don't know which we've got.
                     // Treat it like EUC-JP.  If the data really was EUC-TW, the following two
                     //   bytes will look like a well formed 2 byte char.
                     if (secondByte < 0xa1) {
                         it.error = true;
                     }
                     break buildChar;
                 }

                 if (firstByte == 0x8f) {
                     // Code set 3.
                     // Three byte total char size, two bytes of actual char value.
                     thirdByte    = it.nextByte(det);
                     it.charValue = (it.charValue << 8) | thirdByte;
                     if (thirdByte < 0xa1) {
                         it.error = true;
                     }
                 }
              }

             return (it.done == false);
         }

         /**
          * The charset recognize for EUC-JP.  A singleton instance of this class
          *    is created and kept by the public CharsetDetector class
          */
         static class CharsetRecog_euc_jp extends CharsetRecog_euc {
             static int [] commonChars =
                 // TODO:  This set of data comes from the character frequency-
                 //        of-occurence analysis tool.  The data needs to be moved
                 //        into a resource and loaded from there.
                {0xa1a1, 0xa1a2, 0xa1a3, 0xa1a6, 0xa1bc, 0xa1ca, 0xa1cb, 0xa1d6, 0xa1d7, 0xa4a2,
                 0xa4a4, 0xa4a6, 0xa4a8, 0xa4aa, 0xa4ab, 0xa4ac, 0xa4ad, 0xa4af, 0xa4b1, 0xa4b3,
                 0xa4b5, 0xa4b7, 0xa4b9, 0xa4bb, 0xa4bd, 0xa4bf, 0xa4c0, 0xa4c1, 0xa4c3, 0xa4c4,
                 0xa4c6, 0xa4c7, 0xa4c8, 0xa4c9, 0xa4ca, 0xa4cb, 0xa4ce, 0xa4cf, 0xa4d0, 0xa4de,
                 0xa4df, 0xa4e1, 0xa4e2, 0xa4e4, 0xa4e8, 0xa4e9, 0xa4ea, 0xa4eb, 0xa4ec, 0xa4ef,
                 0xa4f2, 0xa4f3, 0xa5a2, 0xa5a3, 0xa5a4, 0xa5a6, 0xa5a7, 0xa5aa, 0xa5ad, 0xa5af,
                 0xa5b0, 0xa5b3, 0xa5b5, 0xa5b7, 0xa5b8, 0xa5b9, 0xa5bf, 0xa5c3, 0xa5c6, 0xa5c7,
                 0xa5c8, 0xa5c9, 0xa5cb, 0xa5d0, 0xa5d5, 0xa5d6, 0xa5d7, 0xa5de, 0xa5e0, 0xa5e1,
                 0xa5e5, 0xa5e9, 0xa5ea, 0xa5eb, 0xa5ec, 0xa5ed, 0xa5f3, 0xb8a9, 0xb9d4, 0xbaee,
                 0xbbc8, 0xbef0, 0xbfb7, 0xc4ea, 0xc6fc, 0xc7bd, 0xcab8, 0xcaf3, 0xcbdc, 0xcdd1};
             @Override
            String getName() {
                 return "EUC-JP";
             }

             @Override
            CharsetMatch match(CharsetDetector det) {
                 int confidence = match(det, commonChars);
                 return confidence == 0 ? null : new CharsetMatch(det, this, confidence);
             }

             @Override
            public String getLanguage()
             {
                 return "ja";
             }
         }

         /**
          * The charset recognize for EUC-KR.  A singleton instance of this class
          *    is created and kept by the public CharsetDetector class
          */
         static class CharsetRecog_euc_kr extends CharsetRecog_euc {
             static int [] commonChars =
                 // TODO:  This set of data comes from the character frequency-
                 //        of-occurence analysis tool.  The data needs to be moved
                 //        into a resource and loaded from there.
                {0xb0a1, 0xb0b3, 0xb0c5, 0xb0cd, 0xb0d4, 0xb0e6, 0xb0ed, 0xb0f8, 0xb0fa, 0xb0fc,
                 0xb1b8, 0xb1b9, 0xb1c7, 0xb1d7, 0xb1e2, 0xb3aa, 0xb3bb, 0xb4c2, 0xb4cf, 0xb4d9,
                 0xb4eb, 0xb5a5, 0xb5b5, 0xb5bf, 0xb5c7, 0xb5e9, 0xb6f3, 0xb7af, 0xb7c2, 0xb7ce,
                 0xb8a6, 0xb8ae, 0xb8b6, 0xb8b8, 0xb8bb, 0xb8e9, 0xb9ab, 0xb9ae, 0xb9cc, 0xb9ce,
                 0xb9fd, 0xbab8, 0xbace, 0xbad0, 0xbaf1, 0xbbe7, 0xbbf3, 0xbbfd, 0xbcad, 0xbcba,
                 0xbcd2, 0xbcf6, 0xbdba, 0xbdc0, 0xbdc3, 0xbdc5, 0xbec6, 0xbec8, 0xbedf, 0xbeee,
                 0xbef8, 0xbefa, 0xbfa1, 0xbfa9, 0xbfc0, 0xbfe4, 0xbfeb, 0xbfec, 0xbff8, 0xc0a7,
                 0xc0af, 0xc0b8, 0xc0ba, 0xc0bb, 0xc0bd, 0xc0c7, 0xc0cc, 0xc0ce, 0xc0cf, 0xc0d6,
                 0xc0da, 0xc0e5, 0xc0fb, 0xc0fc, 0xc1a4, 0xc1a6, 0xc1b6, 0xc1d6, 0xc1df, 0xc1f6,
                 0xc1f8, 0xc4a1, 0xc5cd, 0xc6ae, 0xc7cf, 0xc7d1, 0xc7d2, 0xc7d8, 0xc7e5, 0xc8ad};

             @Override
            String getName() {
                 return "EUC-KR";
             }

             @Override
            CharsetMatch match(CharsetDetector det) {
                 int confidence = match(det, commonChars);
                 return confidence == 0 ? null : new CharsetMatch(det, this, confidence);
             }

             @Override
            public String getLanguage()
             {
                 return "ko";
             }
         }
     }

     /**
      *
      *   GB-18030 recognizer. Uses simplified Chinese statistics.
      *
      */
     static class CharsetRecog_gb_18030 extends CharsetRecog_mbcs {

         /*
          *  (non-Javadoc)
          *  Get the next character value for EUC based encodings.
          *  Character "value" is simply the raw bytes that make up the character
          *     packed into an int.
          */
         @Override
        boolean nextChar(iteratedChar it, CharsetDetector det) {
             it.error = false;
             int firstByte  = 0;
             int secondByte = 0;
             int thirdByte  = 0;
             int fourthByte = 0;

             buildChar: {
                 firstByte = it.charValue = it.nextByte(det);

                 if (firstByte < 0) {
                     // Ran off the end of the input data
                     it.done = true;
                     break buildChar;
                 }

                 if (firstByte <= 0x80) {
                     // single byte char
                     break buildChar;
                 }

                 secondByte = it.nextByte(det);
                 it.charValue = (it.charValue << 8) | secondByte;

                 if (firstByte >= 0x81 && firstByte <= 0xFE) {
                     // Two byte Char
                     if ((secondByte >= 0x40 && secondByte <= 0x7E) || (secondByte >=80 && secondByte <=0xFE)) {
                         break buildChar;
                     }

                     // Four byte char
                     if (secondByte >= 0x30 && secondByte <= 0x39) {
                         thirdByte = it.nextByte(det);

                         if (thirdByte >= 0x81 && thirdByte <= 0xFE) {
                             fourthByte = it.nextByte(det);

                             if (fourthByte >= 0x30 && fourthByte <= 0x39) {
                                 it.charValue = (it.charValue << 16) | (thirdByte << 8) | fourthByte;
                                 break buildChar;
                             }
                         }
                     }

                     it.error = true;
                     break buildChar;
                 }
             }

             return (it.done == false);
         }

         static int [] commonChars =
             // TODO:  This set of data comes from the character frequency-
             //        of-occurence analysis tool.  The data needs to be moved
             //        into a resource and loaded from there.
            {0xa1a1, 0xa1a2, 0xa1a3, 0xa1a4, 0xa1b0, 0xa1b1, 0xa1f1, 0xa1f3, 0xa3a1, 0xa3ac,
             0xa3ba, 0xb1a8, 0xb1b8, 0xb1be, 0xb2bb, 0xb3c9, 0xb3f6, 0xb4f3, 0xb5bd, 0xb5c4,
             0xb5e3, 0xb6af, 0xb6d4, 0xb6e0, 0xb7a2, 0xb7a8, 0xb7bd, 0xb7d6, 0xb7dd, 0xb8b4,
             0xb8df, 0xb8f6, 0xb9ab, 0xb9c9, 0xb9d8, 0xb9fa, 0xb9fd, 0xbacd, 0xbba7, 0xbbd6,
             0xbbe1, 0xbbfa, 0xbcbc, 0xbcdb, 0xbcfe, 0xbdcc, 0xbecd, 0xbedd, 0xbfb4, 0xbfc6,
             0xbfc9, 0xc0b4, 0xc0ed, 0xc1cb, 0xc2db, 0xc3c7, 0xc4dc, 0xc4ea, 0xc5cc, 0xc6f7,
             0xc7f8, 0xc8ab, 0xc8cb, 0xc8d5, 0xc8e7, 0xc9cf, 0xc9fa, 0xcab1, 0xcab5, 0xcac7,
             0xcad0, 0xcad6, 0xcaf5, 0xcafd, 0xccec, 0xcdf8, 0xceaa, 0xcec4, 0xced2, 0xcee5,
             0xcfb5, 0xcfc2, 0xcfd6, 0xd0c2, 0xd0c5, 0xd0d0, 0xd0d4, 0xd1a7, 0xd2aa, 0xd2b2,
             0xd2b5, 0xd2bb, 0xd2d4, 0xd3c3, 0xd3d0, 0xd3fd, 0xd4c2, 0xd4da, 0xd5e2, 0xd6d0};


         @Override
        String getName() {
             return "GB18030";
         }

         @Override
        CharsetMatch match(CharsetDetector det) {
             int confidence = match(det, commonChars);
             return confidence == 0 ? null : new CharsetMatch(det, this, confidence);
         }

         @Override
        public String getLanguage()
         {
             return "zh";
         }
     }


}
