/*
 * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package build.tools.generatecharacter;

import java.lang.reflect.*;
import java.util.*;

/** Recovers and prints ranges for certain java.lang.Character
    properties. Useful for generating fast-path Latin-1 code. */

public class PrintCharacterRanges {
  static class BooleanRange {
    private int begin;
    private int end;

    BooleanRange(int begin, int end) {
      this.begin = begin;
      this.end   = end;
    }

    int begin() { return begin; }
    int end()   { return end;   }
  }

  private static List/*<BooleanRange>*/ recoverBooleanRanges(String methodName) throws Exception {
    List result = new ArrayList();
    int currentRangeStart = -1;
    Method method = Character.class.getDeclaredMethod(methodName, new Class[] { Character.TYPE });
    if (method == null) {
      throw new RuntimeException("No method \"" + methodName + "\"(C) found");
    }

    for (int i = 0; i <= 255; i++) {
      boolean methodRes = ((Boolean) method.invoke(null, new Object[] { new Character((char) i) })).booleanValue();
      if (methodRes) {
        if (currentRangeStart < 0) {
          currentRangeStart = i;
        }
        if (i == 255) {
          result.add(new BooleanRange(currentRangeStart, i));
        }
      } else {
        if (currentRangeStart >= 0) {
          result.add(new BooleanRange(currentRangeStart, i - 1));
          currentRangeStart = -1;
        }
      }
    }

    return result;
  }

  private static String describe(int num) {
    StringBuffer s = new StringBuffer();
    s.append(num);
    s.append(" ('");
    if (num > 32 && num < 123) {
      s.append((char) num);
    } else {
      s.append("\\u");
      String hex = Long.toHexString(num).toUpperCase();
      for (int i = 0; i < (4 - hex.length()); i++) {
        s.append('0');
      }
      s.append(hex);
    }
    s.append("')");
    return s.toString();
  }

  private static void printBooleanRanges(List/*<BooleanRange>*/ ranges, String methodName) {
    System.out.print(methodName + ":");
    for (Iterator iter = ranges.iterator(); iter.hasNext();) {
      BooleanRange range = (BooleanRange) iter.next();
      System.out.print(" [ " + describe(range.begin()) + ", " + describe(range.end()) + " ]");
    }
    System.out.println("");
  }

  private static void recoverAndPrintBooleanRanges(String methodName) throws Exception {
    List ranges = recoverBooleanRanges(methodName);
    printBooleanRanges(ranges, methodName);
  }

  static class ShiftRange {
    private int begin;
    private int end;
    private int offset;

    ShiftRange(int begin, int end, int offset) {
      this.begin  = begin;
      this.end    = end;
      this.offset = offset;
    }

    int begin()  { return begin;  }
    int end()    { return end;    }
    int offset() { return offset; }
  }

  private static List/*<ShiftRange>*/ recoverShiftRanges(String methodName) throws Exception {
    List result = new ArrayList();
    int currentRangeStart = -1;
    int currentRangeOffset = -1;
    Method method = Character.class.getDeclaredMethod(methodName, new Class[] { Character.TYPE });
    if (method == null) {
      throw new RuntimeException("No method \"" + methodName + "\"(C) found");
    }

    for (int i = 0; i <= 255; i++) {
      char methodRes = ((Character) method.invoke(null, new Object[] { new Character((char) i) })).charValue();
      if (methodRes != i) {
        int offset = methodRes - i;
        if (currentRangeStart < 0) {
          currentRangeStart = i;
        } else if (offset != currentRangeOffset) {
          result.add(new ShiftRange(currentRangeStart, i - 1, currentRangeOffset));
          currentRangeStart = i;
        }
        currentRangeOffset = offset;
        if (i == 255) {
          result.add(new ShiftRange(currentRangeStart, i, currentRangeOffset));
        }
      } else {
        if (currentRangeStart >= 0) {
          result.add(new ShiftRange(currentRangeStart, i - 1, currentRangeOffset));
          currentRangeStart = -1;
        }
      }
    }

    return result;
  }

  private static void printShiftRanges(List/*<ShiftRange>*/ ranges, String methodName) {
    System.out.print(methodName + ":");
    boolean isFirst = true;
    for (Iterator iter = ranges.iterator(); iter.hasNext();) {
      ShiftRange range = (ShiftRange) iter.next();
      if (isFirst) {
        isFirst = false;
      } else {
        System.out.print(", ");
      }
      System.out.print(" [ " + describe(range.begin()) + ", " + describe(range.end()) + " ] -> [ " +
                       describe((range.begin() + range.offset())) + ", " + describe((range.end() + range.offset())) + " ] (" +
                       range.offset() + ")");
    }
    System.out.println("");
  }

  private static void recoverAndPrintShiftRanges(String methodName) throws Exception {
    List ranges = recoverShiftRanges(methodName);
    printShiftRanges(ranges, methodName);
  }

  public static void main(String[] args) {
    try {
      recoverAndPrintBooleanRanges("isDefined");
      recoverAndPrintBooleanRanges("isDigit");
      recoverAndPrintBooleanRanges("isIdentifierIgnorable");
      recoverAndPrintBooleanRanges("isISOControl");
      recoverAndPrintBooleanRanges("isJavaIdentifierPart");
      recoverAndPrintBooleanRanges("isJavaIdentifierStart");
      recoverAndPrintBooleanRanges("isLetter");
      recoverAndPrintBooleanRanges("isLetterOrDigit");
      recoverAndPrintBooleanRanges("isLowerCase");
      recoverAndPrintBooleanRanges("isMirrored");
      recoverAndPrintBooleanRanges("isSpaceChar");
      recoverAndPrintBooleanRanges("isTitleCase");
      recoverAndPrintBooleanRanges("isUnicodeIdentifierPart");
      recoverAndPrintBooleanRanges("isUnicodeIdentifierStart");
      recoverAndPrintBooleanRanges("isUpperCase");
      recoverAndPrintBooleanRanges("isWhitespace");

      recoverAndPrintShiftRanges("toUpperCase");
      recoverAndPrintShiftRanges("toLowerCase");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
