/*
 *******************************************************************************
 * Copyright (C) 2003, International Business Machines Corporation and         *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/stringprep/PunycodeReference.java,v $
 * $Date: 2003/08/27 21:13:14 $
 * $Revision: 1.2 $
 *
 *******************************************************************************
*/

/*
 * 
Disclaimer and license

    Regarding this entire document or any portion of it (including
    the pseudocode and C code), the author makes no guarantees and
    is not responsible for any damage resulting from its use.  The
    author grants irrevocable permission to anyone to use, modify,
    and distribute it in any way that does not diminish the rights
    of anyone else to use, modify, and distribute it, provided that
    redistributed derivative works do not contain misleading author or
    version information.  Derivative works need not be licensed under
    similar terms.

punycode.c 0.4.0 (2001-Nov-17-Sat)
http://www.cs.berkeley.edu/~amc/idn/
Adam M. Costello
http://www.nicemice.net/amc/
*/

package com.ibm.icu.dev.test.stringprep;
import com.ibm.icu.text.StringPrepParseException;
import com.ibm.icu.text.UCharacterIterator;
import com.ibm.icu.text.UTF16;

/**
 * The implementation is direct port of C code in the RFC
 */

public final class PunycodeReference {
    /*** punycode status codes */
    public static final int punycode_success=0;
    public static final int punycode_bad_input=1;   /* Input is invalid.                       */
    public static final int punycode_big_output=2;  /* Output would exceed the space provided. */
    public static final int punycode_overflow =3;    /* Input needs wider integers to process.  */
    
    /*** Bootstring parameters for Punycode ***/
    private static final int base = 36;
    private static final int tmin = 1;
    private static final int tmax = 26;
    private static final int skew = 38;
    private static final int damp = 700;
    private static final int initial_bias = 72;
    private static final int initial_n = 0x80;
    private static final int delimiter = 0x2D;
    
    
    private static final long UNSIGNED_INT_MASK = 0xffffffffL;
    
    /* basic(cp) tests whether cp is a basic code point: */
    private static boolean basic(int cp){
        return (char)(cp) < 0x80;
    }

    /* delim(cp) tests whether cp is a delimiter: */
    private static boolean delim(int cp){
        return ((cp) == delimiter);
    }

    /* decode_digit(cp) returns the numeric value of a basic code */
    /* point (for use in representing integers) in the range 0 to */
    /* base-1, or base if cp is does not represent a value.       */

    private static int decode_digit(int cp)
    {
      return  cp - 48 < 10 ? cp - 22 :  cp - 65 < 26 ? cp - 65 :
              cp - 97 < 26 ? cp - 97 :  base;
    }

    /* encode_digit(d,flag) returns the basic code point whose value      */
    /* (when used for representing integers) is d, which needs to be in   */
    /* the range 0 to base-1.  The lowercase form is used unless flag is  */
    /* nonzero, in which case the uppercase form is used.  The behavior   */
    /* is undefined if flag is nonzero and digit d has no uppercase form. */

    private static char encode_digit(int d, int flag)
    {
      return (char) (d + 22 + (75 * ((d < 26) ? 1 : 0) - (((flag != 0) ? 1 :0) << 5)));
      /*  0..25 map to ASCII a..z or A..Z */
      /* 26..35 map to ASCII 0..9         */
    }

    /* flagged(bcp) tests whether a basic code point is flagged */
    /* (uppercase).  The behavior is undefined if bcp is not a  */
    /* basic code point.                                        */

    private static boolean flagged(int bcp){
         return ((bcp) - 65 < 26);
    }

    /* encode_basic(bcp,flag) forces a basic code point to lowercase */
    /* if flag is zero, uppercase if flag is nonzero, and returns    */
    /* the resulting code point.  The code point is unchanged if it  */
    /* is caseless.  The behavior is undefined if bcp is not a basic */
    /* code point.                                                   */

    private static char encode_basic(int bcp, int flag)
    {
      bcp -= (((bcp - 97) < 26) ? 1 :0 ) << 5;
      boolean mybcp = (bcp - 65 < 26);
      return (char) (bcp + (((flag==0) && mybcp ) ? 1 : 0 ) << 5);
    }

    /*** Platform-specific constants ***/

    /* maxint is the maximum value of a punycode_uint variable: */
    private static long maxint = 0xFFFFFFFFL;
    /* Because maxint is unsigned, -1 becomes the maximum value. */

    /*** Bias adaptation function ***/

    private static int adapt(int delta, int numpoints, boolean firsttime ){
      int k;

      delta = (firsttime==true) ? delta / damp : delta >> 1;
      /* delta >> 1 is a faster way of doing delta / 2 */
      delta += delta / numpoints;

      for (k = 0;  delta > ((base - tmin) * tmax) / 2;  k += base) {
        delta /= base - tmin;
      }

      return k + (base - tmin + 1) * delta / (delta + skew);
    }

    /*** Main encode function ***/

    public static final int encode(   int input_length,
                                      int input[],
                                      char[] case_flags,
                                      int[] output_length,
                                      char output[] ){
      int delta, h, b, out, max_out, bias, j, q, k, t;
      long m,n;
      /* Initialize the state: */

      n = initial_n;
      delta = out = 0;
      max_out = output_length[0];
      bias = initial_bias;

      /* Handle the basic code points: */

      for (j = 0;  j < input_length;  ++j) {
        if (basic(input[j])) {
          if (max_out - out < 2) return punycode_big_output;
          output[out++] = (char)
            (case_flags!=null ?  encode_basic(input[j], case_flags[j]) : input[j]);
        }
        /* else if (input[j] < n) return punycode_bad_input; */
        /* (not needed for Punycode with unsigned code points) */
      }

      h = b = out;

      /* h is the number of code points that have been handled, b is the  */
      /* number of basic code points, and out is the number of characters */
      /* that have been output.                                           */

      if (b > 0) output[out++] = delimiter;

      /* Main encoding loop: */

      while (h < input_length) {
        /* All non-basic code points < n have been     */
        /* handled already.  Find the next larger one: */

        for (m = maxint, j = 0;  j < input_length;  ++j) {
          /* if (basic(input[j])) continue; */
          /* (not needed for Punycode) */
          if (input[j] >= n && input[j] < m) m = input[j];
        }

        /* Increase delta enough to advance the decoder's    */
        /* <n,i> state to <m,0>, but guard against overflow: */

        if (m - n > (maxint - delta) / (h + 1)) return punycode_overflow;
        delta += (m - n) * (h + 1);
        n = m;

        for (j = 0;  j < input_length;  ++j) {
          /* Punycode does not need to check whether input[j] is basic: */
          if (input[j] < n /* || basic(input[j]) */ ) {
            if (++delta == 0) return punycode_overflow;
          }

          if (input[j] == n) {
            /* Represent delta as a generalized variable-length integer: */

            for (q = delta, k = base;  ;  k += base) {
              if (out >= max_out) return punycode_big_output;
              t = k <= bias /* + tmin */ ? tmin :     /* +tmin not needed */
                  k >= bias + tmax ? tmax : k - bias;
              if (q < t) break;
              output[out++] = encode_digit(t + (q - t) % (base - t), 0);
              q = (q - t) / (base - t);
            }

            output[out++] = encode_digit(q, (case_flags !=null) ? case_flags[j] : 0);
            bias = adapt(delta, h + 1, (h == b));
            delta = 0;
            ++h;
          }
        }

        ++delta;
        ++n;
      }

      output_length[0] = out;
      return punycode_success;
    }
    
    public static final StringBuffer encode(StringBuffer input,char[] case_flags)
                               throws StringPrepParseException{
        int[] in = new int[input.length()];
        int inLen = 0;
        int ch;
        StringBuffer result = new StringBuffer();
        UCharacterIterator iter = UCharacterIterator.getInstance(input);
        while((ch=iter.nextCodePoint())!= UCharacterIterator.DONE){
            in[inLen++]=ch;
        }

        int[] outLen =  new int[1];
        outLen[0] = input.length()*4;
        char[] output = new char[outLen[0]];
        int rc = punycode_success;
        for(;;){
            rc = encode(inLen,in,case_flags, outLen, output);
            if(rc==punycode_big_output){
                outLen[0] = outLen[0]*4;
                output = new char[outLen[0]];
                // continue to convert
                continue;
            }
            break;
        }
        if(rc==punycode_success){
            return result.append(output,0,outLen[0]);
        }
        getException(rc);
        return result;
    }

    private static void getException(int rc) 
                   throws StringPrepParseException{
         switch(rc){
             case punycode_big_output:
                throw new StringPrepParseException("The output capacity was not sufficient.",StringPrepParseException.BUFFER_OVERFLOW_ERROR);
             case punycode_bad_input:
                throw new StringPrepParseException("Illegal char found in the input",StringPrepParseException.ILLEGAL_CHAR_FOUND);
             case punycode_overflow:
                throw new StringPrepParseException("Invalid char found in the input",StringPrepParseException.INVALID_CHAR_FOUND);   
         }
        
    }
    private static final int MAX_BUFFER_SIZE = 100;
    
    public static final StringBuffer decode(StringBuffer input,char[] case_flags)
                               throws StringPrepParseException{
        char[] in = input.toString().toCharArray();
        int[] outLen = new int[1];
        outLen[0] = MAX_BUFFER_SIZE;
        int[] output = new int[outLen[0]];
        int rc = punycode_success;
        StringBuffer result = new StringBuffer();
        for(;;){
            rc = decode(input.length(),in, outLen, output,case_flags);
            if(rc==punycode_big_output){
                outLen[0] = output.length * 4;
                output = new int[outLen[0]];
                continue;
            }
            break;
        }
        if(rc==punycode_success){
            for(int i=0; i < outLen[0]; i++ ){
                UTF16.append(result,output[i]);
            }
        }else{
            getException(rc);
        }
        return result;
    }
    
    /*** Main decode function ***/
    public static final int decode(int input_length,
                             char[] input,
                             int[] output_length,
                             int[] output,
                             char[] case_flags ){
      int n, out, i, max_out, bias,
                     b, j, in, oldi, w, k, digit, t;

      /* Initialize the state: */

      n = initial_n;
      out = i = 0;
      max_out = output_length[0];
      bias = initial_bias;

      /* Handle the basic code points:  Let b be the number of input code */
      /* points before the last delimiter, or 0 if there is none, then    */
      /* copy the first b code points to the output.                      */

      for (b = j = 0;  j < input_length;  ++j){
           if (delim(input[j])==true){
                b = j;
           }
      }
      if (b > max_out) return punycode_big_output;

      for (j = 0;  j < b;  ++j) {
        if (case_flags != null) case_flags[out] = (char)(flagged(input[j]) ? 1 : 0);
        if (!basic(input[j])) return punycode_bad_input;
        output[out++] = input[j];
      }

      /* Main decoding loop:  Start just after the last delimiter if any  */
      /* basic code points were copied; start at the beginning otherwise. */

      for (in = b > 0 ? b + 1 : 0;  in < input_length;  ++out) {

        /* in is the index of the next character to be consumed, and */
        /* out is the number of code points in the output array.     */

        /* Decode a generalized variable-length integer into delta,  */
        /* which gets added to i.  The overflow checking is easier   */
        /* if we increase i as we go, then subtract off its starting */
        /* value at the end to obtain delta.                         */

        for (oldi = i, w = 1, k = base;  ;  k += base) {
          if (in >= input_length) return punycode_bad_input;
          digit = decode_digit(input[in++]);
          if (digit >= base) return punycode_bad_input;
          if (digit > (maxint - i) / w) return punycode_overflow;
          i += digit * w;
          t = (k <= bias) /* + tmin */ ? tmin :     /* +tmin not needed */
              (k >= (bias + tmax)) ? tmax : k - bias;
          if (digit < t) break;
          if (w > maxint / (base - t)) return punycode_overflow;
          w *= (base - t);
        }

        bias = adapt(i - oldi, out + 1, (oldi == 0));

        /* i was supposed to wrap around from out+1 to 0,   */
        /* incrementing n each time, so we'll fix that now: */

        if (i / (out + 1) > maxint - n) return punycode_overflow;
        n += i / (out + 1);
        i %= (out + 1);

        /* Insert n at position i of the output: */

        /* not needed for Punycode: */
        /* if (decode_digit(n) <= base) return punycode_invalid_input; */
        if (out >= max_out) return punycode_big_output;

        if (case_flags != null) {
          System.arraycopy(case_flags, i, case_flags,  i + 1, out - i);
          /* Case of last character determines uppercase flag: */
          case_flags[i] = (char)(flagged(input[in - 1]) ? 0 :1);
        }

        System.arraycopy(output, i, output, i + 1,  (out - i));
        output[i++] = n;
      }

      output_length[0] = out;
      return punycode_success;
    }

}
