/*******************************************************************************
 * Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
 * which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/

package org.eclipse.persistence.internal.xr;

// Javase imports
import java.sql.Types;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.w3c.dom.Document;

// Java extension libraries
import javax.xml.namespace.QName;

// EclipseLink imports
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.platform.xml.XMLPlatform;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import static org.eclipse.persistence.internal.helper.ClassConstants.APBYTE;
import static org.eclipse.persistence.internal.helper.ClassConstants.BIGDECIMAL;
import static org.eclipse.persistence.internal.helper.ClassConstants.BIGINTEGER;
import static org.eclipse.persistence.internal.helper.ClassConstants.BOOLEAN;
import static org.eclipse.persistence.internal.helper.ClassConstants.BYTE;
import static org.eclipse.persistence.internal.helper.ClassConstants.CALENDAR;
import static org.eclipse.persistence.internal.helper.ClassConstants.DOUBLE;
import static org.eclipse.persistence.internal.helper.ClassConstants.FLOAT;
import static org.eclipse.persistence.internal.helper.ClassConstants.INTEGER;
import static org.eclipse.persistence.internal.helper.ClassConstants.LONG;
import static org.eclipse.persistence.internal.helper.ClassConstants.Object_Class;
import static org.eclipse.persistence.internal.helper.ClassConstants.SHORT;
import static org.eclipse.persistence.internal.helper.ClassConstants.STRING;
import static org.eclipse.persistence.internal.xr.sxf.SimpleXMLFormat.DEFAULT_SIMPLE_XML_FORMAT_TAG;
import static org.eclipse.persistence.oxm.XMLConstants.ANY_SIMPLE_TYPE_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.BASE_64_BINARY_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.BOOLEAN_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.BYTE_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.DATE_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.DATE_TIME_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.DECIMAL_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.DOUBLE_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.DURATION_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.FLOAT_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.G_DAY_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.G_MONTH_DAY_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.G_MONTH_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.G_YEAR_MONTH_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.G_YEAR_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.HEX_BINARY_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.INTEGER_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.INT_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.LONG_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.QNAME_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.SHORT_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.STRING_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.TIME_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.UNSIGNED_BYTE_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.UNSIGNED_INT_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.UNSIGNED_SHORT_QNAME;

/**
 * <p><b>INTERNAL</b>: provides useful constants, SQL Column <-> to XML name mapping and
 * a few other misc. features
 *
 * @author Mike Norman - michael.norman@oracle.com
 * @since EclipseLink 1.x
 */
@SuppressWarnings("serial")
public class Util {
    public static XMLPlatform XML_PLATFORM = XMLPlatformFactory.getInstance().getXMLPlatform();
    public static Document TEMP_DOC = XML_PLATFORM.createDocument();
    public static final int OPAQUE = 2007;
    public static final String DEFAULT_ATTACHMENT_MIMETYPE = "application/octet-stream";
    public static final String WEB_INF_DIR = "WEB-INF/";
    public static final String WSDL_DIR = "wsdl/";
    public static final String[] META_INF_PATHS = { "META-INF/", "/META-INF/" };
    public static final String DBWS_SERVICE_XML = "eclipselink-dbws.xml";
    public static final String DBWS_OR_LABEL = "dbws-or";
    public static final String DBWS_OX_LABEL = "dbws-ox";
    public static final String DBWS_OR_XML = "eclipselink-" + DBWS_OR_LABEL + ".xml";
    public static final String DBWS_OX_XML = "eclipselink-" + DBWS_OX_LABEL + ".xml";
    public static final String DBWS_SCHEMA_XML = "eclipselink-dbws-schema.xsd";
    public static final String DBWS_WSDL = "eclipselink-dbws.wsdl";
    public static final String DBWS_SESSIONS_XML = "eclipselink-dbws-sessions.xml";
    public static final String DBWS_OR_SESSION_NAME_SUFFIX = DBWS_OR_LABEL + "-session";
    public static final String DBWS_OX_SESSION_NAME_SUFFIX = DBWS_OX_LABEL + "-session";
    public static final String TARGET_NAMESPACE_PREFIX = "ns1";
    public static final String SERVICE_NAMESPACE_PREFIX = "srvc";
    public static final String SERVICE_SUFFIX = "Service";
    public static final String ALL_QUERYNAME = "findAll";
    public static final String PK_QUERYNAME = "findByPrimaryKey";
    public static final String XMLTYPE_STR = "XMLTYPE";
    public static final String DOT_STR = ".";
    public static final String UNDERSCORE_STR = "_";
    public static final String TYPE_STR = "Type";
    public static final String COLLECTION_WRAPPER_STR = "CollectionWrapper";
    public static final String DASH_STR = "-";
    public static final String EMPTY_STR = "";
    public static final char COLON_CHAR = ':';
    public static final char SLASH_CHAR = '/';
    
    /**
     * Convert a SQL name to a valid XML name. Because not all characters that
     * are valid in a SQL name is valid in an XML name, they need to be escaped
     * using a special format. See the Oracle paper,"SQL/XML candidate base
     * document", for more detail
     *
     * @param name
     *            the SQL name
     *
     * @return the escaped valid XML name
     */
    public static String sqlToXmlName(String name) {

        int length = name.length();
        if (length == 0) {
            return name;
        }

        String xmlName = new String();
        int beginAt = 1;
        char firstChar = name.charAt(0);
        // escape : to _x003A_
        if (firstChar == ':') {
            xmlName = xmlName + "_x003A_";
        }
        // escape _ of _x to _x005F_
        else if ((length >= 2) && name.substring(0, 2).equals("_x")) {
            xmlName = xmlName + "_x005F_";
        }
        // check to see if it is a valid first character
        else {
            if ((firstChar >= 0xd800) && (firstChar < 0xdc00)) {
                // surrogate
                if (length > 1) {
                    xmlName += hexEscape((firstChar << 16) | (name.charAt(1) & 0xffff));
                    beginAt = 2;
                } else {
                    xmlName += hexEscape(firstChar);
                }
            } else if (isFirstNameChar(firstChar)) {
                xmlName = xmlName + firstChar;
            } else {
                xmlName = xmlName + hexEscape(firstChar);
            }
        }

        // check each following character to see if it is a valid NameChar
        char c;
        for (int x = beginAt; x < length; x++) {
            c = name.charAt(x);

            if ((c >= 0xd800) && (c < 0xdc00)) {
                // surrogate
                if ((x + 1) < length) {
                    xmlName += hexEscape((c << 16) | (name.charAt(x + 1) & 0xffff));
                    x++;
                } else {
                    xmlName += hexEscape(c);
                }
            } else if (!isNameChar(c)) {
                // escape
                xmlName = xmlName + hexEscape(c);
            } else {
                xmlName = xmlName + c;
            }
        }
        return xmlName;
    }

    /**
     * Convert an escaped XML name back to the original SQL name
     *
     * @param name
     *            the escaped XML name
     *
     * @return the original SQL name
     */
    public static String xmlToSqlName(String name) {

        String sqlName = new String();
        int length = name.length();
        boolean unescapeMode = false;
        String hexString = null;
        char c;
        // step through each one
        for (int x = 0; x < length; x++) {
            c = name.charAt(x);
            if (unescapeMode) {
                // we are in unescape mode
                if (((c >= 'A') && (c <= 'F')) || ((c >= '0') && (c <= '9'))) {
                    // gather the hex string from the escape sequence
                    hexString = hexString + c;
                } else if (c == '_') {
                    // done with escape mode
                    unescapeMode = false;
                    int i;
                    int len;
                    if (hexString != null && (len = hexString.length()) > 4) {
                        char i1 = (char) (Integer.parseInt(hexString.substring(0, len - 4), 16));
                        char i2 = (char) (Integer.parseInt(hexString.substring(len - 4), 16));
                        sqlName += i1;
                        sqlName += i2;
                    } else if ((i = Integer.parseInt(hexString, 16)) == 0xffff) {
                    } else {
                        sqlName += (char) i;
                    }
                } else {
                    // invalid char in escape sequence! write everything into
                    // sqlName as is, or we could throw an exception here
                    // in the future
                    sqlName += ("_x" + hexString + c);
                    unescapeMode = false;
                }
            } else {
                if ((c == '_') && ((x + 1) < length) && (name.charAt(x + 1) == 'x')) {
                    // found escape beginning _x
                    // go into unescape mode
                    unescapeMode = true;
                    hexString = new String();
                    x++;
                } else {
                    // just copy src char to destination
                    sqlName += c;
                }
            }
        }
        return sqlName;
    }

    public static String hexEscape(char c) {
        String outPutString;
        outPutString = Integer.toHexString(c);
        switch (outPutString.length()) {
        case 1:
            outPutString = "_x000" + outPutString.toUpperCase(Locale.US) + "_";
            break;
        case 2:
            outPutString = "_x00" + outPutString.toUpperCase(Locale.US) + "_";
            break;
        case 3:
            outPutString = "_x0" + outPutString.toUpperCase(Locale.US) + "_";
            break;
        case 4:
            outPutString = "_x" + outPutString.toUpperCase(Locale.US) + "_";
            break;
        }
        return outPutString;
    }

    public static String hexEscape(int c) {
        String outPutString;
        outPutString = Integer.toHexString(c);
        switch (outPutString.length()) {
        case 1:
        case 5:
            outPutString = "_x000" + outPutString.toUpperCase(Locale.US) + "_";
            break;
        case 2:
        case 6:
            outPutString = "_x00" + outPutString.toUpperCase(Locale.US) + "_";
            break;
        case 3:
        case 7:
            outPutString = "_x0" + outPutString.toUpperCase(Locale.US) + "_";
            break;
        case 4:
        case 8:
            outPutString = "_x" + outPutString.toUpperCase(Locale.US) + "_";
            break;
        }
        return outPutString;
    }

    /**
     * return true if character can be part of a name
     *
     * @param c -
     *            char to be checked
     * @return true/false
     */
    public static boolean isNameChar(char c) {
        // In most cases the character is less than 256, so this check
        // is made fast. For the rest of the characters the check is
        // based on the conformance tests. XML 1.1 has changed the list
        // of chars allowed, and the check is quite simple. So the
        // complete check based on XML 1.0 is not performed.
        boolean res;
        if (c < 256)
            res = (chartype[c] & (FLETTER | FDIGIT | FMISCNAME)) != 0;
        else {
            // [#x2180-#x2182] | [#x3041-#x3094] | [#x30A1-#x30FA] |
            // [#x3105-#x312C] | [#xAC00-#xD7A3]
            // [#x0E47-#x0E4E]
            if (((c >= 0x2180) && (c <= 0x2182)) || ((c >= 0x3041) && (c <= 0x3094))
                || ((c >= 0x30A1) && (c <= 0x30FA)) || ((c >= 0x3105) && (c <= 0x312C))
                || ((c >= 0xAC00) && (c <= 0xD7A3)) || ((c >= 0x0E47) && (c <= 0x0E4E)))
                res = true;
            else {
                if ((c == 0x02FF) || (c == 0x0346) || (c == 0x0362) || (c == 0x0487)
                    || (c == 0x05A2) || (c == 0x05BA) || (c == 0x05BE) || (c == 0x05C0)
                    || (c == 0x05C3) || (c == 0x0653) || (c == 0x06B8) || (c == 0x06B9)
                    || (c == 0x06E9) || (c == 0x06EE) || (c == 0x0904) || (c == 0x093B)
                    || (c == 0x094E) || (c == 0x0955) || (c == 0x0964) || (c == 0x0984)
                    || (c == 0x09C5) || (c == 0x09C9) || (c == 0x09CE) || (c == 0x09D8)
                    || (c == 0x09E4) || (c == 0x0A03) || (c == 0x0A3D) || (c == 0x0A46)
                    || (c == 0x0A49) || (c == 0x0A4E) || (c == 0x0A80) || (c == 0x0A84)
                    || (c == 0x0ABB) || (c == 0x0AC6) || (c == 0x0ACA) || (c == 0x0ACE)
                    || (c == 0x0B04) || (c == 0x0B3B) || (c == 0x0B44) || (c == 0x0B4A)
                    || (c == 0x0B4E) || (c == 0x0B58) || (c == 0x0B84) || (c == 0x0BC3)
                    || (c == 0x0BC9) || (c == 0x0BD6) || (c == 0x0C0D) || (c == 0x0C45)
                    || (c == 0x0C49) || (c == 0x0C54) || (c == 0x0C81) || (c == 0x0C84)
                    || (c == 0x0CC5) || (c == 0x0CC9) || (c == 0x0CD4) || (c == 0x0CD7)
                    || (c == 0x0D04) || (c == 0x0D45) || (c == 0x0D49) || (c == 0x0D4E)
                    || (c == 0x0D58) || (c == 0x0E3F) || (c == 0x0E3B) || (c == 0x0E4F)
                    || (c == 0x0EBA) || (c == 0x0EBE) || (c == 0x0ECE) || (c == 0x0F1A)
                    || (c == 0x0F36) || (c == 0x0F38) || (c == 0x0F3B) || (c == 0x0F3A)
                    || (c == 0x0F70) || (c == 0x0F85) || (c == 0x0F8C) || (c == 0x0F96)
                    || (c == 0x0F98) || (c == 0x0FB0) || (c == 0x0FB8) || (c == 0x0FBA)
                    || (c == 0x20DD) || (c == 0x20E2) || (c == 0x3030) || (c == 0x309B)
                    || (c == 0x066A) || (c == 0x06FA) || (c == 0x0970) || (c == 0x09F2)
                    || (c == 0x0AF0) || (c == 0x0B70) || (c == 0x0C65) || (c == 0x0CE5)
                    || (c == 0x0CF0) || (c == 0x0D70) || (c == 0x0E5A) || (c == 0x0EDA)
                    || (c == 0x0F2A) || (c == 0x02D2) || (c == 0x03FE) || (c == 0x065F)
                    || (c == 0x0E5C) || (c == 0x0C04))
                    res = false;
                else {
                    res =
                        Character.isLetter(c) || Character.isDigit(c) || c == '-' || c == '_'
                            || c == '.';
                    res = true;
                }
            }
        }
        return res;
    }

    /**
     * return true if character can be part of a name
     *
     * @param c -
     *            char to be checked
     * @return true/false
     */
    public static boolean isFirstNameChar(char c) {
        // In most cases the character is less than 256, so this check
        // is made fast. For the rest of the characters the check is
        // based on the conformance tests. XML 1.1 has changed the list
        // of chars allowed, and the check is quite simple. So the
        // complete check based on XML 1.0 is not performed.
        boolean res;
        if (c < 256)
            res = (chartype[c] & (FLETTER | FSTARTNAME)) != 0;
        else {
            // [#x2180-#x2182] | [#x3041-#x3094] | [#x30A1-#x30FA] |
            // [#x3105-#x312C] | [#xAC00-#xD7A3]
            if (((c >= 0x2180) && (c <= 0x2182)) || (c == 0x3007)
                || ((c >= 0x3021) && (c <= 0x3029)) || ((c >= 0x3041) && (c <= 0x3094))
                || ((c >= 0x30A1) && (c <= 0x30FA)) || ((c >= 0x3105) && (c <= 0x312C))
                || ((c >= 0xAC00) && (c <= 0xD7A3)))
                res = true;
            else {
                if ((c == 0x1101) || (c == 0x1104) || (c == 0x1108) || (c == 0x110A)
                    || (c == 0x110D) || (c == 0x113B) || (c == 0x1141) || (c == 0x114D)
                    || (c == 0x114F) || (c == 0x1151) || (c == 0x1156) || (c == 0x1162)
                    || (c == 0x1164) || (c == 0x1166) || (c == 0x116B) || (c == 0x116F)
                    || (c == 0x1174) || (c == 0x119F) || (c == 0x11AC) || (c == 0x11B6)
                    || (c == 0x11B9) || (c == 0x11BB) || (c == 0x11C3) || (c == 0x11F1)
                    || (c == 0x0132) || (c == 0x0133) || (c == 0x013F) || (c == 0x0140)
                    || (c == 0x0149) || (c == 0x017F) || (c == 0x01C4) || (c == 0x01CC)
                    || (c == 0x01F1) || (c == 0x01F3) || (c == 0x0E46) || (c == 0x113F)
                    || (c == 0x01F6) || (c == 0x01F9) || (c == 0x0230) || (c == 0x03D7)
                    || (c == 0x03DD) || (c == 0x03E1) || (c == 0x040D) || (c == 0x0450)
                    || (c == 0x045D) || (c == 0x04EC) || (c == 0x04ED) || (c == 0x06B8)
                    || (c == 0x06BF) || (c == 0x06CF) || (c == 0x0E2F) || (c == 0x0EAF)
                    || (c == 0x0F6A) || (c == 0x4CFF) || (c == 0x212F) || (c == 0x0587))
                    res = false;
                else
                    res = Character.isLetter(c) || c == '_';
            }
        }
        return res;
    }

    /**
     * Char type table
     */
    static final int chartype[] = new int[256];
    static final int FWHITESPACE = 1;
    static final int FDIGIT = 2;
    static final int FLETTER = 4;
    static final int FMISCNAME = 8;
    static final int FSTARTNAME = 16;
    static {
        for (int i = 0; i < 256; i++) {
            char c = (char) i;
            chartype[i] = 0;
            if ((c == 32) || (c == 9) || (c == 13) || (c == 10))
                chartype[i] = FWHITESPACE;
            if (Character.isLetter(c))
                chartype[i] |= FLETTER;
            if (Character.isDigit(c))
                chartype[i] |= FDIGIT;
        }
        chartype['.'] |= FMISCNAME;
        chartype['-'] |= FMISCNAME;
        chartype['_'] |= FMISCNAME | FSTARTNAME;
        chartype[0xb7] |= FMISCNAME; // Extender
    }

    public static Class<?> getClassFromJDBCType(String typeName, DatabasePlatform databasePlatform) {
        Class<?> clz = (Class<?>)databasePlatform.getClassTypes().get(typeName);
        if (clz == null) {
            return Object_Class;
        }
        return clz;
    }

	public static final QName SXF_QNAME = new QName("", DEFAULT_SIMPLE_XML_FORMAT_TAG);

    public static final Map<QName, Class<?>> SCHEMA_2_CLASS;
    static {
      SCHEMA_2_CLASS = new HashMap<QName, Class<?>>() {{
            put(ANY_SIMPLE_TYPE_QNAME,Object_Class);
            put(BASE_64_BINARY_QNAME, APBYTE);
            put(BOOLEAN_QNAME, BOOLEAN);
            put(BYTE_QNAME, BYTE);
            //put(DATE_QNAME, SQLDATE);
            put(DATE_QNAME, CALENDAR);
            //put(DATE_TIME_QNAME, TIMESTAMP);
            put(DATE_TIME_QNAME, CALENDAR);
            put(DECIMAL_QNAME, BIGDECIMAL);
            put(DOUBLE_QNAME, DOUBLE);
            put(DURATION_QNAME, STRING);
            put(FLOAT_QNAME, FLOAT);
            put(G_YEAR_MONTH_QNAME, STRING);
            put(G_YEAR_QNAME, STRING);
            put(G_MONTH_QNAME, STRING);
            put(G_MONTH_DAY_QNAME, STRING);
            put(G_DAY_QNAME, STRING);
            put(HEX_BINARY_QNAME, APBYTE);
            put(INT_QNAME, INTEGER);
            put(INTEGER_QNAME, BIGINTEGER);
            put(LONG_QNAME, LONG);
            put(QNAME_QNAME, QName.class);
            put(SHORT_QNAME, SHORT);
            put(STRING_QNAME, STRING);
            //put(TIME_QNAME, TIME);
            put(TIME_QNAME, CALENDAR);
            put(UNSIGNED_BYTE_QNAME, SHORT);
            put(UNSIGNED_INT_QNAME, LONG);
            put(UNSIGNED_SHORT_QNAME, INTEGER);
        }};
    }
    
    /**
     * Return the type name to be used for a given JDBC type.  This will
     * typically be used when setting the SQL type and type name on a 
     * stored function/procedure argument.  Currently, the only case 
     * we need to handle in this manner is oracle.xdb.XMLType - here
     * we may set 2007 (OPAQUE) or 2009 (SQLXML).
     * 
     * In the future this method may be required to return more types.
     */
    public static String getTypeNameForJDBCType(int jdbcType) {
        String typeName = null;
        switch (jdbcType) {
        case OPAQUE: 
        case Types.SQLXML:
            typeName = XMLTYPE_STR;
            break;
        default:
            break;
        }
        return typeName;
    }
    
    public static int getJDBCTypeForTypeName(String typeName) {
        int typeCode = -1;
        if (typeName.equals(XMLTYPE_STR)) {
            // we currently use oracle.sql.OPAQUE for XMLType
            typeCode = OPAQUE;
        }
        return typeCode;                
    }
}
