/*   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[]
        {
              "abstract",
              "boolean",
              "break",
              "byte",
              "case",
              "catch",
              "char",
              "class",
              "const",
              "continue",
              "default",
              "do",
              "double",
              "else",
              "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",
              "super",
              "switch",
              "synchronized",
              "this",
              "threadsafe",
              "throw",
              "throws",
              "transient",
              "true", // not a keyword
              "try",
              "void",
              "volatile",
              "while",
        }
    ));

    /*
    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 getJAXRPCClassName( String name )
    {
        name = name.replace('.', '_');
        name = uppercaseFirstLetter( name );

        if (isValidJavaIdentifer(name))
        {
            return name;
        }
        else
        {
            return "_" + name;
        }
    }

    public static String getJAXRPCMethodName(String name)
    {
        name = name.replace('.','_');
        name = lowercaseFirstLetter(name);

        if (isValidJavaIdentifer(name))
        {
            return name;
        }
        else
        {
            return "_" + name;
        }
    }

    public static XMLName getXMLNameFromClass(Class clazz)
    {
        String uri = NameUtil.getNamespaceFromPackage(clazz);
        String lname = NameUtil.getRootClassNameFromClass(clazz.getName());
        XMLName xsd_name = new Name(uri, lname);
        return xsd_name;
    }
    */

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

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

        java_pkg = getPackageFromNamespace(uri);

        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;
        return i;
    }

    private static String jls77String(String name)
    {
        StringBuffer buf = new StringBuffer(name);
        for (int i = 0; i < name.length(); i++)
        {
            if (!Character.isJavaIdentifierPart(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)
    {
        // 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 >= 0 && uri.substring(0, i).equals("java"))
            result = Arrays.asList(StringUtils.split(uri.substring(i + 1), '.'));

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

        StringBuffer buf = new StringBuffer();
        for (Iterator it = result.iterator(); it.hasNext(); )
        {
            buf.append(nonJavaKeyword(lowerCamelCase((String)it.next())));
            buf.append('.');
        }
        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)
    {
        StringBuffer buf = new StringBuffer();
        List words = splitWords(xml_name);

        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)
    {
        StringBuffer buf = new StringBuffer();
        List words = splitWords(xml_name);

        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)
    {
        StringBuffer buf = new StringBuffer();
        List words = splitWords(xml_name);

        if (words.size() > 0)
        {
            String first = ((String)words.get(0)).toLowerCase();
            char f = first.charAt(0);
            if (!Character.isJavaIdentifierStart(f))
                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)
    {
        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));
            if (prefix != PUNCT && current == PUNCT)
            {
                addCapped(list, name.substring(start, i));
                while ((current = getCharClass(name.charAt(i))) == 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)
    {
        //ordering is important here.
        if (isPunctuation(c))
            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)
    {
        return (c == HYPHEN
              || c == PERIOD
              || c == COLON
              || c == USCORE
              || c == DOT
              || 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 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);
    }

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