/*
 * Copyright (c) 1998, 2020 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 v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink

package org.eclipse.persistence.internal.xr;

// Javase imports
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.oxm.Constants.ANY_SIMPLE_TYPE_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.BASE_64_BINARY_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.BOOLEAN_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.BYTE_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.DATE_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.DATE_TIME_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.DECIMAL_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.DOUBLE_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.DURATION_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.FLOAT_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.G_DAY_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.G_MONTH_DAY_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.G_MONTH_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.G_YEAR_MONTH_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.G_YEAR_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.HEX_BINARY_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.INTEGER_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.INT_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.LONG_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.QNAME_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.SHORT_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.STRING_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.TIME_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.UNSIGNED_BYTE_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.UNSIGNED_INT_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.UNSIGNED_SHORT_QNAME;
import static org.eclipse.persistence.internal.xr.sxf.SimpleXMLFormat.DEFAULT_SIMPLE_XML_FORMAT_TAG;

import java.sql.Types;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

// 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 org.w3c.dom.Document;

/**
 * <p><b>INTERNAL</b>: provides useful constants, SQL Column &lt;-&gt; 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 final XMLPlatform XML_PLATFORM = XMLPlatformFactory.getInstance().getXMLPlatform();
    public static final 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;
        }

        StringBuilder xmlName = new StringBuilder();
        int beginAt = 1;
        char firstChar = name.charAt(0);
        // escape : to _x003A_
        if (firstChar == ':') {
            xmlName.append("_x003A_");
        }
        // escape _ of _x to _x005F_
        else if ((length >= 2) && name.substring(0, 2).equals("_x")) {
            xmlName.append("_x005F_");
        }
        // check to see if it is a valid first character
        else {
            if ((firstChar >= 0xd800) && (firstChar < 0xdc00)) {
                // surrogate
                if (length > 1) {
                    xmlName.append(hexEscape((firstChar << 16) | (name.charAt(1) & 0xffff)));
                    beginAt = 2;
                } else {
                    xmlName.append(hexEscape(firstChar));
                }
            } else if (isFirstNameChar(firstChar)) {
                xmlName.append(firstChar);
            } else {
                xmlName.append(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.append(hexEscape((c << 16) | (name.charAt(x + 1) & 0xffff)));
                    x++;
                } else {
                    xmlName.append(hexEscape(c));
                }
            } else if (!isNameChar(c)) {
                // escape
                xmlName.append(hexEscape(c));
            } else {
                xmlName.append(c);
            }
        }
        return xmlName.toString();
    }

    /**
     * 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 = "";
        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;
                    if (hexString != null) {
                        int i;
                        int len;
                        if ((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 {
                            try {
                                i = Integer.parseInt(hexString, 16);
                                if (i != 0xffff) {
                                    sqlName += (char) i;
                                }
                            } catch (NumberFormatException nfe) {
                                throw new RuntimeException(nfe);
                            }
                        }
                    }
                } 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 = "";
                    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 {
                    // Character.isLetter(c) || Character.isDigit(c) || '-' || '-' || '.'
                    // is known to be true at this point
                    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 {
                    //Character.isLetter(c) || c == '_' is known to be true here
                    res = true;
                }
            }
        }
        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 = 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 = Collections.unmodifiableMap(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;
    }
}
