/*   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)
    {
        StringBuffer buf = new StringBuffer(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;

        StringBuffer buf = new StringBuffer(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);
    }
}
