/*
 * Copyright (c) 2013, 2021 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:
//     David McCann - 2.6.0 - July 09, 2013 - Initial Implementation
package org.eclipse.persistence.tools.metadata.generation;

import static org.eclipse.persistence.platform.database.oracle.plsql.OraclePLSQLTypes.XMLType;

import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.tools.oracleddl.metadata.DatabaseType;
import org.eclipse.persistence.tools.oracleddl.metadata.FieldType;
import org.eclipse.persistence.tools.oracleddl.metadata.NumericType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLCursorType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLType;
import org.eclipse.persistence.tools.oracleddl.metadata.ProcedureType;
import org.eclipse.persistence.tools.oracleddl.metadata.SizedType;

/**
 * Utility class typically used when constructing JPA/JAXB metadata from a
 * list of meta-model database types.
 *
 */
public class Util {
    public static final String ARRAY_STR = "ARRAY";
    public static final String BIGINT_STR = "BIGINT";
    public static final String BINARY_STR = "BINARY";
    public static final String BLOB_STR = "BLOB";
    public static final String BOOLEAN_STR = "BOOLEAN";
    public static final String CHAR_STR = "CHAR";
    public static final String CLOB_STR = "CLOB";
    public static final String DATE_STR = "DATE";
    public static final String DECIMAL_STR = "DECIMAL";
    public static final String DOUBLE_STR = "DOUBLE";
    public static final String FLOAT_STR = "FLOAT";
    public static final String INTEGER_STR = "INTEGER";
    public static final String LONG_STR = "LONG";
    public static final String LONGRAW_STR = "LONG RAW";
    public static final String LONGVARBINARY_STR = "LONGVARBINARY";
    public static final String NCHAR_STR = "NCHAR";
    public static final String NCLOB_STR = "NCLOB";
    public static final String NUMBER_STR = "NUMBER";
    public static final String NUMERIC_STR = "NUMERIC";
    public static final String NVARCHAR_STR = "NVARCHAR";
    public static final String NVARCHAR2_STR = "NVARCHAR2";
    public static final String OTHER_STR = "OTHER";
    public static final String RAW_STR = "RAW";
    public static final String REAL_STR = "REAL";
    public static final String ROWID_STR = "ROWID";
    public static final String ROWTYPE_STR = "%ROWTYPE";
    public static final String SMALLINT_STR = "SMALLINT";
    public static final String STRUCT_STR = "STRUCT";
    public static final String TIME_STR = "TIME";
    public static final String TIMESTAMP_STR = "TIMESTAMP";
    public static final String TINYINT_STR = "TINYINT";
    public static final String UROWID_STR = "UROWID";
    public static final String VARBINARY_STR = "VARBINARY";
    public static final String VARCHAR_STR = "VARCHAR";
    public static final String VARCHAR2_STR = "VARCHAR2";
    public static final String BINARY_INTEGER_STR = "BINARY_INTEGER";
    public static final String PLS_INTEGER_STR = "PLS_INTEGER";
    public static final String NATURAL_STR = "NATURAL";
    public static final String POSITIVE_STR = "POSITIVE";
    public static final String SIGNTYPE_STR = "SIGNTYPE";
    public static final String BINARY_INTEGER_TYPE_STR = "BinaryInteger";
    public static final String PLS_BOOLEAN_TYPE_STR = "PLSQLBoolean";
    public static final String PLS_INTEGER_TYPE_STR = "PLSQLInteger";
    public static final String NATURAL_TYPE_STR = "Natural";
    public static final String POSITIVE_TYPE_STR = "Positive";
    public static final String SIGNTYPE_TYPE_STR = "SignType";

    public static final String SYS_XMLTYPE_STR = "SYS.XMLTYPE";
    public static final String XMLTYPE_STR = "XMLTYPE";
    public static final String _TYPE_STR = "_TYPE";

    public static final String COMMA = ",";
    public static final String SINGLE_SPACE = " ";
    public static final String COMMA_SPACE_STR = COMMA + SINGLE_SPACE;

    // for CRUD operations
    public static final String ALL_QUERYNAME = "findAll";
    public static final String PK_QUERYNAME = "findByPrimaryKey";
    public static final String CREATE_OPERATION_NAME = "create";
    public static final String UPDATE_OPERATION_NAME = "update";
    public static final String REMOVE_OPERATION_NAME = "delete";
    public static final String OPEN_BRACKET = "(";
    public static final String CLOSE_BRACKET = ")";
    public static final String TYPE_STR = "Type";
    public static final String SELECT_FROM_STR = "SELECT * FROM ";
    public static final String WHERE_STR = " WHERE ";
    public static final String AND_STR = " AND ";
    public static final String SET_STR = " SET ";
    public static final String VALUES_STR = " VALUES ";
    public static final String UPDATE_STR = "UPDATE ";
    public static final String INSERT_STR = "INSERT INTO ";
    public static final String DELETE_STR = "DELETE FROM ";
    public static final String EQUALS_BINDING1_STR = " = ?1";
    public static final String EQUALS_BINDING_STR = " = ?";
    public static final String QUESTION_STR = "?";


    // SQL class names
    public static final String ARRAY_CLS_STR = "java.sql.Array";
    public static final String NCLOB_CLS_STR = "java.sql.NClob";
    public static final String OPAQUE_CLS_STR = "java.sql.Struct";
    public static final String ROWID_CLS_STR = "java.sql.RowId";
    public static final String STRUCT_CLS_STR = "oracle.sql.OPAQUE";
    public static final String ORACLE_TIMESTAMP_CLS_STR = "oracle.sql.TIMESTAMP";

    // JDK class names
    static final String ARRAYLIST_CLS_STR = "java.util.ArrayList";

    // direction types
    static final String IN_STR = "IN";
    static final String INOUT_STR = "IN_OUT";
    static final String OUT_STR = "OUT";
    static final String OUT_CURSOR_STR = "OUT_CURSOR";
    static final String CURSOR_STR = "CURSOR";
    static final String RESULT_STR = "RESULT";

    // misc
    public static final String DOT = ".";
    public static final String PERCENT = "%";
    public static final String UNDERSCORE = "_";

    public static final String ITEMS_FLD_STR = "items";
    public static final String ITEMS_COL_STR = "ITEMS";

    public static final int OPAQUE = 2007;

    /**
     * Returns a unqualified entity class name based on a given table or type name.
     * The returned string will contain an upper case first char, with the
     * remaining chars in lower case format.
     */
    public static String getUnqualifiedEntityName(String tableName) {
        String first = tableName.substring(0, 1).toUpperCase();
        String rest = tableName.toLowerCase().substring(1);
        return first.concat(rest);
    }

    /**
     * Returns a entity class name based on a given table or type name. The returned
     * string will contain an upper case first char, with the remaining chars in
     * lower case format.  The packageName will be prepended to the Entity name
     * if non-null.
     */
    public static String getEntityName(String tableName, String packageName) {
        String entityName = getUnqualifiedEntityName(tableName);
        return packageName == null ? entityName : packageName + DOT + entityName;
    }

    /**
     * Return the JDBC type name for a given type String.
     */
    public static String getJDBCTypeName(String typeName) {
        // this is inefficient and should be rewritten such that checking is done once only
        return getJDBCTypeNameFromType(getJDBCTypeFromTypeName(typeName));
    }

    /**
     * Return the JDBC type (as int) for a given type name.
     */
    public static int getJDBCTypeFromTypeName(String typeName) {
        if (typeName.equals(NUMERIC_STR)) {
            return Types.NUMERIC;
        }
        if (typeName.equals(VARCHAR_STR) || typeName.equals(VARCHAR2_STR)) {
            return Types.VARCHAR;
        }
        if (typeName.equals(NVARCHAR_STR) || typeName.equals(NVARCHAR2_STR)) {
            return Types.NVARCHAR;
        }
        if (typeName.equals(DATE_STR)) {
            return Types.DATE;
        }
        if (typeName.equals(TIME_STR)) {
            return Types.TIME;
        }
        if (typeName.equals(TIMESTAMP_STR)) {
            return Types.TIMESTAMP;
        }
        if (typeName.equals(DECIMAL_STR)) {
            return Types.DECIMAL;
        }
        if (typeName.equals(INTEGER_STR)) {
            return Types.INTEGER;
        }
        if (typeName.equals(CHAR_STR)) {
            return Types.CHAR;
        }
        if (typeName.equals(NCHAR_STR)) {
            return Types.NCHAR;
        }
        if (typeName.equals(FLOAT_STR)) {
            return Types.FLOAT;
        }
        if (typeName.equals(REAL_STR)) {
            return Types.REAL;
        }
        if (typeName.equals(DOUBLE_STR)) {
            return Types.DOUBLE;
        }
        if (typeName.equals(BINARY_STR)) {
            return Types.BINARY;
        }
        if (typeName.equals(BLOB_STR)) {
            return Types.BLOB;
        }
        if (typeName.equals(CLOB_STR) ||
                 typeName.equals(LONG_STR))  {
            return Types.CLOB;
        }
        if (typeName.equals(NCLOB_STR)) {
            return Types.NCLOB;
        }
        if (typeName.equals(RAW_STR) ||
                typeName.equals(LONGRAW_STR)) {
            return Types.LONGVARBINARY;
        }
        if (typeName.equals(ROWID_STR)) {
            return Types.VARCHAR;
        }
        if (typeName.equals(UROWID_STR)) {
            return Types.VARCHAR;
        }
        if (typeName.equals(BIGINT_STR)) {
            return Types.BIGINT;
        }
        if (typeName.equals(STRUCT_STR)) {
            return Types.STRUCT;
        }
        if (typeName.equals(ARRAY_STR)) {
            return Types.ARRAY;
        }
        if (typeName.equals(ROWID_STR)) {
            return Types.ROWID;
        }
        if (typeName.equalsIgnoreCase(XMLTYPE_STR) ||
                 typeName.equalsIgnoreCase(SYS_XMLTYPE_STR)) {
            return Types.VARCHAR;
        }
        if (typeName.equals(BOOLEAN_STR)  ||
                 typeName.equals(INTEGER_STR)  ||
                 typeName.equals(SMALLINT_STR) ||
                 typeName.equals(TINYINT_STR)) {
            return Types.INTEGER;
        }
        return Types.OTHER;
    }

    /**
     * Return the JDBC type name for a given JDBC type code.
     */
    public static String getJDBCTypeNameFromType(int jdbcType) {
        String typeName = null;
        switch (jdbcType) {
            case Types.NUMERIC:
                typeName = NUMERIC_STR;
                break;
            case Types.VARCHAR:
                typeName = VARCHAR_STR;
                break;
            case Types.NVARCHAR:
                typeName = NVARCHAR_STR;
                break;
            case Types.DECIMAL:
                typeName = DECIMAL_STR;
                break;
            case Types.CHAR:
                typeName = CHAR_STR;
                break;
            case Types.NCHAR:
                typeName = NCHAR_STR;
                break;
            case Types.FLOAT:
                typeName = FLOAT_STR;
                break;
            case Types.REAL:
                typeName = REAL_STR;
                break;
            case Types.DOUBLE:
                typeName = DOUBLE_STR;
                break;
            case Types.BINARY:
                typeName = BINARY_STR;
                break;
            case Types.BLOB:
                typeName = BLOB_STR;
                break;
            case Types.CLOB:
                typeName = CLOB_STR;
                break;
            case Types.NCLOB:
                typeName = NCLOB_STR;
                break;
            case Types.VARBINARY :
                typeName = LONGVARBINARY_STR;
                break;
            case Types.LONGVARBINARY:
                typeName = LONGVARBINARY_STR;
                break;
            case Types.DATE:
                typeName = DATE_STR;
                break;
            case Types.TIME:
                typeName = TIME_STR;
                break;
            case Types.TIMESTAMP:
                typeName = TIMESTAMP_STR;
                break;
            case Types.BIGINT:
                typeName = BIGINT_STR;
                break;
            case Types.ARRAY:
                typeName = ARRAY_STR;
                break;
            case Types.STRUCT:
                typeName = STRUCT_STR;
                break;
            case Types.ROWID:
                typeName = ROWID_STR;
                break;
            default:
                typeName = OTHER_STR;
                break;
        }
        return typeName;
    }

    /**
     * Return the Class name for a given type name using the provided DatabasePlatform.
     * Object.class.getName() will be returned if the DatabasePlatform returns null.
     */
    public static String getClassNameFromJDBCTypeName(String typeName, DatabasePlatform databasePlatform) {
        return getClassFromJDBCTypeName(typeName, databasePlatform).getName();
    }

    /**
     * Return the Class for a given type name using the provided DatabasePlatform.  Object.class will
     * be returned if the DatabasePlatform returns null.
     */
    public static Class<?> getClassFromJDBCTypeName(String typeName, DatabasePlatform databasePlatform) {
        Class<?> clz = databasePlatform.getClassTypes().get(typeName);
        if (clz == null) {
            return CoreClassConstants.OBJECT;
        }
        return clz;
    }

    /**
     * Alter the given type name if required.
     */
    protected static String processTypeName(String typeName) {
        if (!(getJDBCTypeFromTypeName(typeName) == Types.OTHER)) {
            if (typeName.equals(XMLTYPE_STR)) {
                typeName = XMLType.name();
            } else {
                // OR Metadata doesn't handle VARCHAR2
                if (typeName.equals(VARCHAR2_STR)) {
                    typeName = VARCHAR_STR;
                }
                // for BOOLEAN we want to wrap the type in a PLSQLrecord (in ORMetadata.getDatabaseTypeEnum) to
                // force the appropriate conversion method in PLSQLStoredProcedureCall (declare block, etc)
                if (!typeName.equals(BOOLEAN_STR)) {
                    typeName = typeName.concat(_TYPE_STR);
                }
            }
        } else {
            String oPLSQLTypeName = getOraclePLSQLTypeForName(typeName);
            if (oPLSQLTypeName != null) {
                typeName = oPLSQLTypeName;
            }
        }
        return typeName;
    }

    /**
     * Returns a Java class name based on a given qualified name.  If the name has
     * a package prepended to it, the the returned string  will be  in the format
     * 'packagename.Name', otherwise the format will be 'Name'.   For  example,  given
     * the name 'test.EMPLOYEE', the  method would return  the string 'test.Employee'.
     *
     */
    public static String getGeneratedJavaClassName(String name) {
        int dotIdx = name.lastIndexOf(DOT);
        if (dotIdx == -1) {
            // no package
            return getGeneratedJavaClassName(name, null);
        }
        String packageName = name.substring(0, dotIdx).toLowerCase();
        String typeName = name.substring(dotIdx + 1);
        String first = typeName.substring(0, 1).toUpperCase();
        String rest = typeName.toLowerCase().substring(1);
        return packageName + DOT + first + rest;
    }

    /**
     * Returns a Java class name based on a given name and package.  The returned
     * string  will be  in the format  'packagename.Name'.   For  example,  given
     * the name 'EMPLOYEE'  and packageName 'TEST', the  method would return  the
     * string 'test.Employee'.
     *
     */
    public static String getGeneratedJavaClassName(String name, String packageName) {
        String first = name.substring(0, 1).toUpperCase();
        String rest = name.toLowerCase().substring(1);
        return packageName == null || packageName.length() == 0 ? first + rest : packageName.toLowerCase() + DOT + first + rest;
    }

    /**
     * Return a qualified type name for the given DatabaseType. If the type is a
     * PLSQLType or a PLSQLCursor, and there is a package name available on the
     * type's parent, a string will be returned in the format 'package.typename'.
     * Otherwise the type name will be returned.
     */
    public static String getQualifiedTypeName(DatabaseType dbType) {
        if (dbType.isPLSQLType()) {
            String packageName = ((PLSQLType) dbType).getParentType().getPackageName();
            // for %ROWTYPE we build a record with no package name - need to check for null
            return packageName != null ? packageName + DOT + dbType.getTypeName() : dbType.getTypeName();
        }

        if (dbType.isPLSQLCursorType()) {
            // handle cursor
            PLSQLCursorType cursor = ((PLSQLCursorType) dbType);
            return cursor.getParentType().getPackageName() + DOT + cursor.getCursorName();
        }

        return dbType.getTypeName();
    }

    /**
     * Return a qualified compatible type name for the given DatabaseType. If the type is a
     * PLSQLType, and there is a package name available on the type's parent, a string will
     * be returned in the format 'package_typename'. Otherwise the type name will be
     * returned. A compatible type is the JDBC type equivalent of a PL/SQL type.
     */
    public static String getQualifiedCompatibleTypeName(DatabaseType dbType) {
        String packageName = null;

        if (dbType.isPLSQLType()) {
            PLSQLType plsqlType = (PLSQLType) dbType;
            packageName = plsqlType.getParentType().getPackageName();
        }

        return packageName != null ? packageName + UNDERSCORE + dbType.getTypeName() : dbType.getTypeName();
    }


    /**
     * Indicates if a given argument type name is considered a PL/SQL scalar
     * argument, i.e. is one of BOOLEAN, BINARY_INTEGER, PLS_INTEGER, etc.
     */
    public static boolean isArgPLSQLScalar(String argTypeName) {
        return argTypeName.equals("BOOLEAN")
            || argTypeName.equals("PLS_INTEGER")
            || argTypeName.equals("BINARY_INTEGER")
            || argTypeName.equals("NATURAL")
            || argTypeName.equals("POSITIVE")
            || argTypeName.equals("SIGNTYPE");
    }

    /**
     * Return the Oracle PL/SQL name for a given PL/SQL scalar type.
     */
    public static String getOraclePLSQLTypeForName(String typeName) {
        if (typeName.equals(BINARY_INTEGER_STR))
            return BINARY_INTEGER_TYPE_STR;
        if (typeName.equals(BOOLEAN_STR))
            return PLS_BOOLEAN_TYPE_STR;
        if (typeName.equals(PLS_INTEGER_STR))
            return PLS_INTEGER_TYPE_STR;
        if (typeName.equals(NATURAL_STR))
            return NATURAL_TYPE_STR;
        if (typeName.equals(POSITIVE_STR))
            return POSITIVE_TYPE_STR;
        if (typeName.equals(SIGNTYPE_STR))
            return SIGNTYPE_TYPE_STR;
        return null;
    }

    /**
     * Return the attribute-type name for a given FieldType.
     *
     * For CHAR sized type, java.lang.Character will be returned.
     * For CHAR non-sized type, java.lang.String will be returned.
     * For non-CHAR type, the database platform will be used to get the type name.
     * If the type to be returned is oracle.sql.Timestamp, java.sql.Timestamp will be
     * returned instead (to handle conversion issue with Oracle11Platform)
     */
    protected static String getAttributeTypeNameForFieldType(FieldType fldType, DatabasePlatform dbPlatform) {
        String typeName = getJDBCTypeName(fldType.getTypeName());
        String attributeType;
        if (CHAR_STR.equalsIgnoreCase(typeName) && fldType.getEnclosedType().isSizedType()) {
            SizedType sizedType = (SizedType) fldType.getEnclosedType();
            if (sizedType.getSize() == 1) {
                attributeType = ClassConstants.CHAR.getName();
            } else {
                attributeType = ClassConstants.STRING.getName();
            }
        } else {
            attributeType = getClassNameFromJDBCTypeName(typeName.toUpperCase(), dbPlatform);
        }
        // handle issue with java.sql.Timestamp conversion and Oracle11 platform
        if (attributeType.contains(ORACLE_TIMESTAMP_CLS_STR)) {
            attributeType = ClassConstants.TIMESTAMP.getName();
        } else if (attributeType.contains(ClassConstants.ABYTE.getName())) {
            attributeType = ClassConstants.APBYTE.getName();
        }
        return attributeType;
    }

    /**
     * Return the type name to be used for a given database type.  The given
     * DatabaseType's typeName attribute is typically returned, however, in
     * some cases special handling may be required.  For example, in the
     * case of a NumericType instance, "DECIMAL" should be used for the
     * type name.
     */
    protected static String getTypeNameForDatabaseType(DatabaseType dataType) {
        String typeName = dataType.getTypeName();
        if (dataType.isNumericType()) {
            NumericType numericDataType = (NumericType)dataType;
            if (numericDataType.getScale() > 0) {
                typeName = DECIMAL_STR;
            }
        }
        return typeName;
    }

    /**
     * Convenience method that detects multiple procedures with the same procedure
     * name, and updates the overload value on the relevant ProcedureTypes
     * accordingly.
     *
     * The first ProcedureType will have an overload value of 0, the second 1,
     * and so on.
     */
    protected static void handleOverloading(List<ProcedureType> procedures) {
        Map<String, List<ProcedureType>> overloadMap = new HashMap<String, List<ProcedureType>>();
        for (ProcedureType procedure : procedures) {
            String procedureName = procedure.getProcedureName();
            List<ProcedureType> multipleProcedures = overloadMap.get(procedureName);
            if (multipleProcedures == null) {
                multipleProcedures = new ArrayList<ProcedureType>();
                overloadMap.put(procedureName, multipleProcedures);
            }
            multipleProcedures.add(procedure);
        }
        for (List<ProcedureType> procs : overloadMap.values()) {
            if (procs.size() > 1) {
                for (int i = 0, len = procs.size(); i < len; i++) {
                    procs.get(i).setOverload(i);
                }
            }
        }

    }
}
