/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed 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.xmlbeans.impl.common;

import javax.xml.namespace.QName;
import java.util.*;

public class NameUtil {
    // punctuation characters
    public final static char HYPHEN = '\u002D';
    public final static char PERIOD = '\u002E';
    public final static char COLON = '\u003A';
    public final static char USCORE = '\u005F';
    public final static char DOT = '\u00B7';
    public final static char TELEIA = '\u0387';
    public final static char AYAH = '\u06DD';
    public final static char ELHIZB = '\u06DE';

    private final static boolean DEBUG = false;

    private final static Set javaWords = new HashSet(Arrays.asList(
        new String[]
            {
                "assert",
                "abstract",
                "boolean",
                "break",
                "byte",
                "case",
                "catch",
                "char",
                "class",
                "const",
                "continue",
                "default",
                "do",
                "double",
                "else",
                "enum", // since JDK1.5
                "extends",
                "false", // not a keyword
                "final",
                "finally",
                "float",
                "for",
                "goto",
                "if",
                "implements",
                "import",
                "instanceof",
                "int",
                "interface",
                "long",
                "native",
                "new",
                "null", // not a keyword
                "package",
                "private",
                "protected",
                "public",
                "return",
                "short",
                "static",
                "strictfp",
                "super",
                "switch",
                "synchronized",
                "this",
                "threadsafe",
                "throw",
                "throws",
                "transient",
                "true", // not a keyword
                "try",
                "void",
                "volatile",
                "while",
            }
    ));

    private final static Set extraWords = new HashSet(Arrays.asList(
        new String[]
            {
                "i",          // used for indexes
                "target",     // used for parameter
                "org",        // used for package names
                "com",        // used for package names
            }
    ));

    /*
    private final static Set javaNames = new HashSet(Arrays.asList(
        new String[]
        {
            "CharSequence",
            "Cloneable",
            "Comparable",
            "Runnable",

            "Boolean",
            "Byte",
            "Character",
            "Class",
            "ClassLoader",
            "Compiler",
            "Double",
            "Float",
            "InheritableThreadLocal",
            "Integer",
            "Long",
            "Math",
            "Number",
            "Object",
            "Package",
            "Process",
            "Runtime",
            "RuntimePermission",
            "SecurityManager",
            "Short",
            "StackTraceElement",
            "StrictMath",
            "String",
            "StringBuffer",
            "System",
            "Thread",
            "ThreadGroup",
            "ThreadLocal",
            "Throwable",
            "Void",

            "ArithmeticException",
            "ArrayIndexOutOfBoundsException",
            "ArrayStoreException",
            "ClassCastException",
            "ClassNotFoundException",
            "CloneNotSupportedException",
            "Exception",
            "IllegalAccessException",
            "IllegalArgumentException",
            "IllegalMonitorStateException",
            "IllegalStateException",
            "IllegalThreadStateException",
            "IndexOutOfBoundsException",
            "InstantiationException",
            "InterruptedException",
            "NegativeArraySizeException",
            "NoSuchFieldException",
            "NoSuchMethodException",
            "NullPointerException",
            "NumberFormatException",
            "RuntimeException",
            "SecurityException",
            "StringIndexOutOfBoundsException",
            "UnsupportedOperationException",

            "AbstractMethodError",
            "AssertionError",
            "ClassCircularityError",
            "ClassFormatError",
            "Error",
            "ExceptionInInitializerError",
            "IllegalAccessError",
            "IncompatibleClassChangeError",
            "InstantiationError",
            "InternalError",
            "LinkageError",
            "NoClassDefFoundError",
            "NoSuchFieldError",
            "NoSuchMethodError",
            "OutOfMemoryError",
            "StackOverflowError",
            "ThreadDeath",
            "UnknownError",
            "UnsatisfiedLinkError",
            "UnsupportedClassVersionError",
            "VerifyError",
            "VirtualMachineError",
        }
    ));
    */

    private final static Set javaNames = new HashSet(Arrays.asList(
        new String[]
            {
                // 1. all the Java.lang classes [1.4.1 JDK].
                "CharSequence",
                "Cloneable",
                "Comparable",
                "Runnable",

                "Boolean",
                "Byte",
                "Character",
                "Class",
                "ClassLoader",
                "Compiler",
                "Double",
                "Float",
                "InheritableThreadLocal",
                "Integer",
                "Long",
                "Math",
                "Number",
                "Object",
                "Package",
                "Process",
                "Runtime",
                "RuntimePermission",
                "SecurityManager",
                "Short",
                "StackTraceElement",
                "StrictMath",
                "String",
                "StringBuffer",
                "System",
                "Thread",
                "ThreadGroup",
                "ThreadLocal",
                "Throwable",
                "Void",

                "ArithmeticException",
                "ArrayIndexOutOfBoundsException",
                "ArrayStoreException",
                "ClassCastException",
                "ClassNotFoundException",
                "CloneNotSupportedException",
                "Exception",
                "IllegalAccessException",
                "IllegalArgumentException",
                "IllegalMonitorStateException",
                "IllegalStateException",
                "IllegalThreadStateException",
                "IndexOutOfBoundsException",
                "InstantiationException",
                "InterruptedException",
                "NegativeArraySizeException",
                "NoSuchFieldException",
                "NoSuchMethodException",
                "NullPointerException",
                "NumberFormatException",
                "RuntimeException",
                "SecurityException",
                "StringIndexOutOfBoundsException",
                "UnsupportedOperationException",

                "AbstractMethodError",
                "AssertionError",
                "ClassCircularityError",
                "ClassFormatError",
                "Error",
                "ExceptionInInitializerError",
                "IllegalAccessError",
                "IncompatibleClassChangeError",
                "InstantiationError",
                "InternalError",
                "LinkageError",
                "NoClassDefFoundError",
                "NoSuchFieldError",
                "NoSuchMethodError",
                "OutOfMemoryError",
                "StackOverflowError",
                "ThreadDeath",
                "UnknownError",
                "UnsatisfiedLinkError",
                "UnsupportedClassVersionError",
                "VerifyError",
                "VirtualMachineError",

                // 2. other classes used as primitive types by xml beans
                "BigInteger",
                "BigDecimal",
                "Enum",
                "Date",
                "GDate",
                "GDuration",
                "QName",
                "List",

                // 3. the top few org.apache.xmlbeans names
                "XmlObject",
                "XmlCursor",
                "XmlBeans",
                "SchemaType",
            }
    ));

    public static boolean isValidJavaIdentifier(String id) {
        if (id == null) {
            throw new IllegalArgumentException("id cannot be null");
        }

        int len = id.length();
        if (len == 0) {
            return false;
        }

        if (javaWords.contains(id)) {
            return false;
        }

        if (!Character.isJavaIdentifierStart(id.charAt(0))) {
            return false;
        }

        for (int i = 1; i < len; i++) {
            if (!Character.isJavaIdentifierPart(id.charAt(i))) {
                return false;
            }
        }

        return true;
    }

    public static String getClassNameFromQName(QName qname) {
        return getClassNameFromQName(qname, false);
    }

    public static String getClassNameFromQName(QName qname, boolean useJaxRpcRules) {
        String java_type = upperCamelCase(qname.getLocalPart(), useJaxRpcRules);

        String uri = qname.getNamespaceURI();
        String java_pkg = null;

        java_pkg = getPackageFromNamespace(uri, useJaxRpcRules);

        if (java_pkg != null) {
            return java_pkg + "." + java_type;
        } else {
            return java_type;
        }
    }

    private static final String JAVA_NS_PREFIX = "java:";
    private static final String LANG_PREFIX = "java.";

    public static String getNamespaceFromPackage(final Class clazz) {
        Class curr_clazz = clazz;

        while (curr_clazz.isArray()) {
            curr_clazz = curr_clazz.getComponentType();
        }

        String fullname = clazz.getName();
        int lastdot = fullname.lastIndexOf('.');
        String pkg_name = lastdot < 0 ? "" : fullname.substring(0, lastdot);

        //special case for builtin types
        /*
        if (curr_clazz.isPrimitive())
        {
            pkg_name = c.getJavaLanguageNamespaceUri();
        }
        else if (pkg_name.startsWith(LANG_PREFIX))
        {
            final String rem_str = pkg_name.substring(LANG_PREFIX.length());
            pkg_name = c.getJavaLanguageNamespaceUri() + "." + rem_str;
        }
        */
        return JAVA_NS_PREFIX + pkg_name;
    }

    private static boolean isUriSchemeChar(char ch) {
        return (ch >= 'a' && ch <= 'z' ||
                ch >= 'A' && ch <= 'Z' ||
                ch >= '0' && ch <= '9' ||
                ch == '-' || ch == '.' || ch == '+');
    }

    private static boolean isUriAlphaChar(char ch) {
        return (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z');
    }

    private static int findSchemeColon(String uri) {
        int len = uri.length();
        if (len == 0) {
            return -1;
        }
        if (!isUriAlphaChar(uri.charAt(0))) {
            return -1;
        }
        int i;
        for (i = 1; i < len; i++) {
            if (!isUriSchemeChar(uri.charAt(i))) {
                break;
            }
        }
        if (i == len) {
            return -1;
        }
        if (uri.charAt(i) != ':') {
            return -1;
        }
        // consume consecutive colons
        for (; i < len; i++) {
            if (uri.charAt(i) != ':') {
                break;
            }
        }
        // for the "scheme:::" case, return len-1
        return i - 1;
    }

    private static String jls77String(String name) {
        StringBuilder buf = new StringBuilder(name);
        for (int i = 0; i < name.length(); i++) {
            // We need to also make sure that our package names don't contain the
            // "$" character in them, which, although a valid Java identifier part,
            // would create confusion when trying to generate fully-qualified names
            if (!Character.isJavaIdentifierPart(buf.charAt(i)) || '$' == buf.charAt(i)) {
                buf.setCharAt(i, '_');
            }
        }
        if (buf.length() == 0 || !Character.isJavaIdentifierStart(buf.charAt(0))) {
            buf.insert(0, '_');
        }
        if (isJavaReservedWord(name)) {
            buf.append('_');
        }
        return buf.toString();
    }

    private static List splitDNS(String dns) {
        // JAXB says: only split+reverse DNS if TLD matches known TLDs or ISO 3166
        // We are ignoring this now (TH)

        List result = new ArrayList();

        int end = dns.length();
        int begin = dns.lastIndexOf('.');
        for (; begin != -1; begin--) {
            if (dns.charAt(begin) == '.') {
                result.add(jls77String(dns.substring(begin + 1, end)));
                end = begin;
            }
        }
        result.add(jls77String(dns.substring(0, end)));

        // JAXB draft example implies removal of www
        if (result.size() >= 3 &&
            ((String) result.get(result.size() - 1)).toLowerCase().equals("www")) {
            result.remove(result.size() - 1);
        }

        return result;
    }

    private static String processFilename(String filename) {
        // JAXB says: strip 2 or 3 letter extension or ".html"

        int i = filename.lastIndexOf('.');
        if (i > 0 && (
            i + 1 + 2 == filename.length() ||
            i + 1 + 3 == filename.length() ||
            "html".equals(filename.substring(i + 1).toLowerCase()))) {
            return filename.substring(0, i);
        }

        return filename;
    }

    public static String getPackageFromNamespace(String uri) {
        return getPackageFromNamespace(uri, false);
    }

    public static String getPackageFromNamespace(String uri, boolean useJaxRpcRules) {
        // special case: no namespace -> package "noNamespace"
        if (uri == null || uri.length() == 0) {
            return "noNamespace";
        }

        // apply draft JAXB rules
        int len = uri.length();
        int i = findSchemeColon(uri);
        List result = null;

        if (i == len - 1) {
            // XMLBEANS-57: colon is at end so just use scheme as the package name
            result = new ArrayList();
            result.add(uri.substring(0, i));
        } else if (i >= 0 && uri.substring(0, i).equals("java")) {
            result = Arrays.asList(uri.substring(i + 1).split("\\."));
        } else {
            result = new ArrayList();
            outer:
            for (i = i + 1; i < len; ) {
                while (uri.charAt(i) == '/') {
                    if (++i >= len) {
                        break outer;
                    }
                }
                int start = i;
                while (uri.charAt(i) != '/') {
                    if (++i >= len) {
                        break;
                    }
                }
                int end = i;
                result.add(uri.substring(start, end));
            }
            if (result.size() > 1) {
                result.set(result.size() - 1, processFilename((String) result.get(result.size() - 1)));
            }

            if (result.size() > 0) {
                List splitdns = splitDNS((String) result.get(0));
                result.remove(0);
                result.addAll(0, splitdns);
            }
        }

        StringBuilder buf = new StringBuilder();
        for (Iterator it = result.iterator(); it.hasNext(); ) {
            String part = nonJavaKeyword(lowerCamelCase((String) it.next(), useJaxRpcRules, true));
            if (part.length() > 0) {
                buf.append(part);
                buf.append('.');
            }
        }
        if (buf.length() == 0) {
            return "noNamespace";
        }
        if (useJaxRpcRules) {
            return buf.substring(0, buf.length() - 1).toLowerCase();
        }
        return buf.substring(0, buf.length() - 1); // chop off extra dot
    }

    public static void main(String[] args) {
        for (int i = 0; i < args.length; i++) {
            System.out.println(upperCaseUnderbar(args[i]));
        }
    }

    /**
     * Returns a upper-case-and-underbar string using the JAXB rules.
     * Always starts with a capital letter that is a valid
     * java identifier start. (If JAXB rules don't produce
     * one, then "X_" is prepended.)
     */
    public static String upperCaseUnderbar(String xml_name) {
        StringBuilder buf = new StringBuilder();
        List words = splitWords(xml_name, false);

        final int sz = words.size() - 1;
        if (sz >= 0 && !Character.isJavaIdentifierStart(((String) words.get(0)).charAt(0))) {
            buf.append("X_");
        }

        for (int i = 0; i < sz; i++) {
            buf.append((String) words.get(i));
            buf.append(USCORE);
        }

        if (sz >= 0) {
            buf.append((String) words.get(sz));
        }

        //upcase entire buffer
        final int len = buf.length();
        for (int j = 0; j < len; j++) {
            char c = buf.charAt(j);
            buf.setCharAt(j, Character.toUpperCase(c));
        }

        return buf.toString();
    }

    /**
     * Returns a camel-cased string using the JAXB rules.
     * Always starts with a capital letter that is a valid
     * java identifier start. (If JAXB rules don't produce
     * one, then "X" is prepended.)
     */
    public static String upperCamelCase(String xml_name) {
        return upperCamelCase(xml_name, false);
    }

    /**
     * Returns a camel-cased string, but either JAXB or JAX-RPC rules
     * are used
     */
    public static String upperCamelCase(String xml_name, boolean useJaxRpcRules) {
        StringBuilder buf = new StringBuilder();
        List words = splitWords(xml_name, useJaxRpcRules);

        if (words.size() > 0) {
            if (!Character.isJavaIdentifierStart(((String) words.get(0)).charAt(0))) {
                buf.append("X");
            }

            Iterator itr = words.iterator();
            while (itr.hasNext()) {
                buf.append((String) itr.next());
            }
        }
        return buf.toString();
    }

    /**
     * Returns a camel-cased string using the JAXB rules,
     * where the first component is lowercased. Note that
     * if the first component is an acronym, the whole
     * thigns gets lowercased.
     * Always starts with a lowercase letter that is a valid
     * java identifier start. (If JAXB rules don't produce
     * one, then "x" is prepended.)
     */
    public static String lowerCamelCase(String xml_name) {
        return lowerCamelCase(xml_name, false, true);
    }

    /**
     * Returns a camel-cased string using the JAXB or JAX-RPC rules
     */
    public static String lowerCamelCase(String xml_name, boolean useJaxRpcRules,
                                        boolean fixGeneratedName) {
        StringBuilder buf = new StringBuilder();
        List words = splitWords(xml_name, useJaxRpcRules);

        if (words.size() > 0) {
            String first = ((String) words.get(0)).toLowerCase();
            char f = first.charAt(0);
            if (!Character.isJavaIdentifierStart(f) && fixGeneratedName) {
                buf.append("x");
            }
            buf.append(first);

            Iterator itr = words.iterator();
            itr.next(); // skip already-lowercased word
            while (itr.hasNext()) {
                buf.append((String) itr.next());
            }
        }
        return buf.toString();
    }

    public static String upperCaseFirstLetter(String s) {
        if (s.length() == 0 || Character.isUpperCase(s.charAt(0))) {
            return s;
        }

        StringBuilder buf = new StringBuilder(s);
        buf.setCharAt(0, Character.toUpperCase(buf.charAt(0)));
        return buf.toString();
    }


    /**
     * split an xml name into words via JAXB approach, upcasing first
     * letter of each word as needed, if upcase is true
     * <p>
     * ncname is xml ncname (i.e. no colons).
     */
    private static void addCapped(List list, String str) {
        if (str.length() > 0) {
            list.add(upperCaseFirstLetter(str));
        }
    }

    public static List splitWords(String name, boolean useJaxRpcRules) {
        List list = new ArrayList();
        int len = name.length();
        int start = 0;
        int prefix = START;
        for (int i = 0; i < len; i++) {
            int current = getCharClass(name.charAt(i), useJaxRpcRules);
            if (prefix != PUNCT && current == PUNCT) {
                addCapped(list, name.substring(start, i));
                while ((current = getCharClass(name.charAt(i), useJaxRpcRules)) == PUNCT) {
                    if (++i >= len) {
                        return list;
                    }
                }
                start = i;
            } else if ((prefix == DIGIT) != (current == DIGIT) ||
                       (prefix == LOWER && current != LOWER) ||
                       (isLetter(prefix) != isLetter(current))) {
                addCapped(list, name.substring(start, i));
                start = i;
            } else if (prefix == UPPER && current == LOWER && i > start + 1) {
                addCapped(list, name.substring(start, i - 1));
                start = i - 1;
            }
            prefix = current;
        }
        addCapped(list, name.substring(start));
        return list;
    }

    //char classes
    private final static int START = 0;
    private final static int PUNCT = 1;
    private final static int DIGIT = 2;
    private final static int MARK = 3;
    private final static int UPPER = 4;
    private final static int LOWER = 5;
    private final static int NOCASE = 6;

    public static int getCharClass(char c, boolean useJaxRpcRules) {
        //ordering is important here.
        if (isPunctuation(c, useJaxRpcRules)) {
            return PUNCT;
        } else if (Character.isDigit(c)) {
            return DIGIT;
        } else if (Character.isUpperCase(c)) {
            return UPPER;
        } else if (Character.isLowerCase(c)) {
            return LOWER;
        } else if (Character.isLetter(c)) {
            return NOCASE;
        } else if (Character.isJavaIdentifierPart(c)) {
            return MARK;
        } else {
            return PUNCT; // not covered by JAXB: treat it as punctuation
        }
    }

    private static boolean isLetter(int state) {
        return (state == UPPER
                || state == LOWER
                || state == NOCASE);
    }

    public static boolean isPunctuation(char c, boolean useJaxRpcRules) {
        return (c == HYPHEN
                || c == PERIOD
                || c == COLON
                || c == DOT
                || (c == USCORE && !useJaxRpcRules)
                || c == TELEIA
                || c == AYAH
                || c == ELHIZB);
    }

    /**
     * Intended to be applied to a lowercase-starting identifier that
     * may collide with a Java keyword.  If it does collide, this
     * prepends the letter "x".
     */
    public static String nonJavaKeyword(String word) {
        if (isJavaReservedWord(word)) {
            return 'x' + word;
        }
        return word;
    }

    /**
     * Intended to be applied to a lowercase-starting identifier that
     * may collide with a Java keyword.  If it does collide, this
     * prepends the letter "x".
     */
    public static String nonExtraKeyword(String word) {
        if (isExtraReservedWord(word, true)) {
            return word + "Value";
        }
        return word;
    }

    /**
     * Intended to be applied to an uppercase-starting identifier that
     * may collide with a java.lang.* classname.  If it does collide, this
     * prepends the letter "X".
     */
    public static String nonJavaCommonClassName(String name) {
        if (isJavaCommonClassName(name)) {
            return "X" + name;
        }
        return name;
    }

    private static boolean isJavaReservedWord(String word) {
        return isJavaReservedWord(word, true);
    }

    private static boolean isJavaReservedWord(String word, boolean ignore_case) {
        if (ignore_case) {
            word = word.toLowerCase();
        }
        return javaWords.contains(word);
    }

    private static boolean isExtraReservedWord(String word, boolean ignore_case) {
        if (ignore_case) {
            word = word.toLowerCase();
        }
        return extraWords.contains(word);
    }

    public static boolean isJavaCommonClassName(String word) {
        return javaNames.contains(word);
    }
}
