/*   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() ||
                filename.substring(i + 1).toLowerCase() == "html"))
        {
            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

       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);
    }
}
