/*
 * Copyright (c) 1998, 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:
//     Oracle - initial API and implementation from Oracle TopLink
//     tware - added handling of database delimiters
//     03/24/2011-2.3 Guy Pelletier
//       - 337323: Multi-tenant with shared schema support (part 1)
//     05/30/2012-2.4 Guy Pelletier
//       - 354678: Temp classloader is still being used during metadata processing
//     02/11/2013-2.5 Guy Pelletier
//       - 365931: @JoinColumn(name="FK_DEPT",insertable = false, updatable = true) causes INSERT statement to include this data value that it is associated with
package org.eclipse.persistence.internal.helper;

//javase imports
import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedActionException;

import static java.lang.Integer.MIN_VALUE;

//EclipseLink imports
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.core.helper.CoreField;
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;

/**
 * INTERNAL:
 * <p><b>Purpose</b>:
 * Define a fully qualified field name.<p>
 * <b>Responsibilities</b>:    <ul>
 * <li> Know its name and its table.
 * </ul>
 * @see DatabaseTable
 */
public class DatabaseField implements Cloneable, Serializable, CoreField  {
    /** Variables used for generating DDL **/
    protected int scale;
    protected int length;
    protected int precision;
    protected boolean isUnique;
    protected boolean isNullable;
    protected boolean isUpdatable;
    protected boolean isInsertable;
    protected boolean isCreatable;
    protected boolean isPrimaryKey;
    protected String columnDefinition;

    /** Column name of the field. */
    protected String name;

    /** PERF: Cache fully qualified table.field-name. */
    protected String qualifiedName;

    /** Fields table (encapsulates name + creator). */
    protected DatabaseTable table;

    /**
     * Respective Java type desired for the field's value, used to optimize performance and for binding.
     * PERF: Allow direct variable access from getObject.
     */
    public transient Class type;
    public String typeName; // shadow variable - string name of above Class type variable

    /**
     * Respective JDBC type of the field's value.
     * This overrides the class type, which the JDBC type is normally computed from.
     * PERF: Allow direct variable access from getObject.
     */
    public int sqlType;

    /**
     * Store normal index of field in result set to optimize performance.
     * PERF: Allow direct variable access from getIndicatingNoEntry.
     */
    public int index;

    protected boolean useDelimiters = false;

    /**
     * If this is set, it will be used in determining equality (unless delimiters are used) and the hashcode.
     * @see getNameForComparisons
     */
    protected String nameForComparisons;

    /**
     * setting to true will cause getNameForComparisons to lazy initialize nameForComparisons using
     * the value from getName().toUpperCase().
     */
    protected boolean useUpperCaseForComparisons = false;

    /**
     * used to represent the value when it has not being defined
     */
    public static final int NULL_SQL_TYPE = MIN_VALUE;

    /**
     * Returns true if this field was translated.
     */
    protected boolean isTranslated = false;

    /**
     * Indicates whether the field should be kept in the record after the object is created.
     * Used by ObjectLevelReadQuery ResultSetAccessOptimization.
     */
    public boolean keepInRow;

    public DatabaseField() {
        this("", new DatabaseTable());
    }

    public DatabaseField(String qualifiedName) {
        this(qualifiedName, null, null);
    }

    public DatabaseField(String qualifiedName, String startDelimiter, String endDelimiter) {
        this.index = -1;
        this.sqlType = NULL_SQL_TYPE;
        int index = qualifiedName.lastIndexOf('.');

        if (index == -1) {
            setName(qualifiedName, startDelimiter, endDelimiter);
            this.table = new DatabaseTable();
        } else {
            setName(qualifiedName.substring(index + 1, qualifiedName.length()), startDelimiter, endDelimiter);
            this.table = new DatabaseTable(qualifiedName.substring(0, index), startDelimiter, endDelimiter);
        }
        initDDLFields();
    }

    public DatabaseField(String fieldName, String tableName) {
        this(fieldName, new DatabaseTable(tableName));
    }

    public DatabaseField(String fieldName, DatabaseTable databaseTable) {
        this(fieldName, databaseTable, null, null);
    }

    public DatabaseField(String fieldName, DatabaseTable databaseTable, String startDelimiter, String endDelimiter) {
        this.index = -1;
        this.sqlType = NULL_SQL_TYPE;
        setName(fieldName, startDelimiter, endDelimiter);
        this.table = databaseTable;
        initDDLFields();
    }

    /**
     * Inits the DDL generation fields with our defaults. Note: we used to
     * initialize the length to the JPA default of 255 but since this default
     * value should only apply for string fields we set it to 0 to indicate
     * that it was not specified and rely on the default (255) to come from
     * individual platforms.
     */
    public void initDDLFields() {
        scale = 0;
        length = 0;
        precision = 0;
        isUnique = false;
        isNullable = true;
        isUpdatable = true;
        isInsertable = true;
        isCreatable = true;
        isPrimaryKey = false;
        columnDefinition = "";
    }

    /**
     * The table is not cloned because it is treated as an automatic value.
     */
    @Override
    public DatabaseField clone() {
        try {
            return (DatabaseField)super.clone();
        } catch (CloneNotSupportedException exception) {
            throw new InternalError(exception.getMessage());
        }
    }

    /*
     * INTERNAL:
     * Convert all the class-name-based settings in this mapping to actual
     * class-based settings. This method is implemented by subclasses as
     * necessary.
     * @param classLoader
     */
    public void convertClassNamesToClasses(ClassLoader classLoader) {
        if (type == null && typeName != null) {
            try {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    try {
                        type = AccessController.doPrivileged(new PrivilegedClassForName<>(typeName, true, classLoader));
                    } catch (PrivilegedActionException e) {
                        throw ValidationException.classNotFoundWhileConvertingClassNames(typeName, e.getException());
                    }
                } else {
                    type = org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName(typeName, true, classLoader);
                }
            } catch (Exception exception) {
                throw ValidationException.classNotFoundWhileConvertingClassNames(typeName, exception);
            }
        }
    }

    /**
     * Determine whether the receiver is equal to a DatabaseField.
     * Return true if the receiver and field have the same name and table.
     * Also return true if the table of the receiver or field are unspecified,
     * ie. have no name.
     */
    @Override
    public boolean equals(Object object) {
        if (!(object instanceof DatabaseField)) {
            return false;
        }

        return equals((DatabaseField)object);
    }

    /**
     * Determine whether the receiver is equal to a DatabaseField.
     * Return true if the receiver and field have the same name and table.
     * Also return true if the table of the receiver or field are unspecified,
     * ie. have no name.
     */
    public boolean equals(DatabaseField field) {
        if (this == field) {
            return true;
        }

        if (field != null) {
            // PERF: Optimize common cases first.
            // PERF: Use direct variable access.
            if (getQualifiedName().equals(field.getQualifiedName())) {
                return true;
            }

            //preserve old behavior if static shouldIgnoreCaseOnFieldComparisons is set
            if (DatabasePlatform.shouldIgnoreCaseOnFieldComparisons()) {
                if (this.name.equalsIgnoreCase(field.name)) {
                    //getTableName will cause NPE if there isn't a table.  use hasTableName instead
                    if ((!hasTableName()) || (!field.hasTableName())) {
                        return true;
                    }
                    return (this.table.equals(field.table));
                }
            } else {
                String ourNameToCompare;
                String fieldNameToCompare;
                if (field.shouldUseDelimiters() || shouldUseDelimiters()) {
                    ourNameToCompare = this.name;
                    fieldNameToCompare = field.name;
                } else {
                    ourNameToCompare = getNameForComparisons();
                    fieldNameToCompare = field.getNameForComparisons();
                }

                if (this.name.equals(field.name) || ourNameToCompare.equals(fieldNameToCompare)) {
                    //getTableName will cause NPE if there isn't a table.  use hasTableName instead
                    if ((!hasTableName()) || (!field.hasTableName())) {
                        return true;
                    }
                    return (this.table.equals(field.table));
                }
            }
        }

        return false;
    }

    /**
     * Get the SQL fragment that is used when generating the DDL for the column.
     */
    public String getColumnDefinition() {
        return this.columnDefinition;
    }

    /**
     * Return the expected index that this field will occur in the result set
     * row. This is used to optimize performance of database row field lookups.
     */
    public int getIndex() {
        return index;
    }

    /**
     * Used to specify the column length when generating DDL.
     */
    public int getLength() {
        return this.length;
    }

    /**
     * Return the unqualified name of the field.
     */
    @Override
    public String getName() {
        return name;
    }

    /**
     * Returns this fields name with database delimiters if useDelimiters is true.
     * This method should be called any time the field name is requested for writing SQL.
     */
    public String getNameDelimited(DatasourcePlatform platform) {
        if (this.useDelimiters){
            return platform.getStartDelimiter() + this.name + platform.getEndDelimiter();
        }
        return this.name;
    }

    /**
     * Returns the precision for a decimal column when generating DDL.
     */
    public int getPrecision() {
        return this.precision;
    }

    public String getQualifiedName(){
        if (this.qualifiedName == null) {
            if (hasTableName()) {
                this.qualifiedName = this.table.getQualifiedName() + "." + getName();
            } else {
                this.qualifiedName = getName();
            }
        }
        return this.qualifiedName;
    }

    /**
     * Return the qualified name of the field.
     * PERF: Cache the qualified name.
     */
    public String getQualifiedNameDelimited(DatasourcePlatform platform) {
        if (hasTableName()) {
            return this.table.getQualifiedNameDelimited(platform) + "." + getNameDelimited(platform);
        } else {
            return getNameDelimited(platform);
        }
    }
    /**
     * Returns the scale for a decimal column when generating DDL.
     */
    public int getScale() {
        return this.scale;
    }

    public DatabaseTable getTable() {
        return table;
    }

    public String getTableName() {
        return getTable().getName();
    }

    public void setTableName(String tableName) {
        setTable(new DatabaseTable(tableName));
    }

    @Override
    public Class getType() {
        if ((this.type == null) && (this.typeName != null)) {
            convertClassNamesToClasses(getClass().getClassLoader());
        }
        return this.type;
    }

    public String getTypeName() {
        return typeName;
    }

    public void setTypeName(String typeName) {
        this.typeName = typeName;
    }

    /**
     * Return the JDBC type that corresponds to the field.
     * The JDBC type is normally determined from the class type,
     * but this allows it to be overridden for types that do not match directly to a Java type,
     * such as MONEY or ARRAY, STRUCT, XMLTYPE, etc.
     * This can be used for binding or stored procedure usage.
     */
    public int getSqlType() {
        return sqlType;
    }

    /**
     * Return the hashcode of the name, because it is fairly unique.
     */
    @Override
    public int hashCode() {
        return getNameForComparisons().hashCode();
    }

    public boolean hasTableName() {
        if (this.table == null) {
            return false;
        }
        if (this.table.getName() == null) {
            return false;
        }
        return !(this.table.getName().equals(""));
    }

    /**
     *  PUBLIC:
     *  Return if this is an ObjectRelationalDatabaseField.
     */
    public boolean isObjectRelationalDatabaseField(){
        return false;
    }

    /**
     * Used to specify whether the column should be included in SQL UPDATE
     * statements.
     */
    public boolean isInsertable() {
        return this.isInsertable;
    }

    /**
     * Used for generating DDL. Returns true if the database column is
     * nullable.
     */
    public boolean isNullable() {
        return this.isNullable;
    }

    /**
     * Used to specify whether the column should be included in the primary
     * on the database table.
     */
    public boolean isPrimaryKey() {
        return this.isPrimaryKey;
    }

    /**
     * Return true if this database field is a translation.
     */
    public boolean isTranslated() {
        return this.isTranslated;
    }

    /**
     * Used for generating DDL. Returns true if the field is a unique key.
     */
    public boolean isUnique() {
        return this.isUnique;
    }

    /**
     * Returns true is this database field should be read only.
     */
    public boolean isReadOnly() {
        return (! isUpdatable && ! isInsertable);
    }

    public boolean keepInRow() {
        return keepInRow;
    }

    /**
     * Returns whether the column should be included in SQL INSERT
     * statements.
     */
    public boolean isUpdatable() {
        return this.isUpdatable;
    }

    /**
     * Reset the field's name and table from the qualified name.
     */
    public void resetQualifiedName(String qualifiedName) {
        setIndex(-1);
        int index = qualifiedName.lastIndexOf('.');

        if (index == -1) {
            setName(qualifiedName);
            getTable().setName("");
            getTable().setTableQualifier("");
        } else {
            setName(qualifiedName.substring(index + 1, qualifiedName.length()));
            getTable().setPossiblyQualifiedName(qualifiedName.substring(0, index));
        }
    }

    /**
     * Set the SQL fragment that is used when generating the DDL for the column.
     */
    public void setColumnDefinition(String columnDefinition) {
        this.columnDefinition = columnDefinition;
    }

    /**
     * Set the expected index that this field will occur in the result set row.
     * This is used to optimize performance of database row field lookups.
     */
    public void setIndex(int index) {
        this.index = index;
    }

    /**
     * Used to specify whether the column should be included in SQL UPDATE
     * statements.
     */
    public void setInsertable(boolean isInsertable) {
        this.isInsertable = isInsertable;
    }

    public void setKeepInRow(boolean keepInRow) {
        this.keepInRow = keepInRow;
    }

    /**
     * Set the isTranslated flag.
     */
    public void setIsTranslated(boolean isTranslated) {
        this.isTranslated = isTranslated;
    }

    /**
     * Used to specify the column length when generating DDL.
     */
    public void setLength(int length) {
        this.length = length;
    }

    /**
     * Set the unqualified name of the field.
     */
    @Override
    public void setName(String name) {
        setName(name, null, null);
    }

    /**
     * Set the unqualified name of the field.
     *
     * If the name contains database delimiters, they will be stripped and a flag will be set to have them
     * added when the DatabaseField is written to SQL
     */
    public void setName(String name, DatasourcePlatform platform){
        setName(name, platform.getStartDelimiter(), platform.getEndDelimiter());
    }

    /**
     * Set the unqualified name of the field.
     *
     * If the name contains database delimiters, they will be stripped and a flag will be set to have them
     * added when the DatabaseField is written to SQL
     */
    public void setName(String name, String startDelimiter, String endDelimiter) {
        if ((startDelimiter != null) && (endDelimiter != null) && !startDelimiter.equals("")&& !endDelimiter.equals("") && name.startsWith(startDelimiter) && name.endsWith(endDelimiter)){
            this.name = name.substring(startDelimiter.length(), name.length() - endDelimiter.length());
            this.useDelimiters = true;
        } else {
            this.name = name;
        }
        this.nameForComparisons = null;
        this.qualifiedName = null;
    }

    /**
     * Used for generating DDL. Set to true if the database column is
     * nullable.
     */
    public void setNullable(boolean isNullable) {
        this.isNullable = isNullable;
    }

    /**
     * Used to specify the precision for a decimal column when generating DDL.
     */
    public void setPrecision(int precision) {
        this.precision = precision;
    }

    /**
     * Used to specify whether the column should be included in primary key
     * on the database table.
     */
    public void setPrimaryKey(boolean isPrimaryKey) {
        this.isPrimaryKey = isPrimaryKey;
    }

    /**
     * Used to specify the scale for a decimal column when generating DDL.
     */
    public void setScale(int scale) {
        this.scale = scale;
    }

    /**
     * Set the JDBC type that corresponds to the field.
     * The JDBC type is normally determined from the class type,
     * but this allows it to be overridden for types that do not match directly
     * to a Java type, such as MONEY or ARRAY, STRUCT, XMLTYPE, etc.
     * This can be used for binding or stored procedure usage.
     */
    public void setSqlType(int sqlType) {
        this.sqlType = sqlType;
    }

    /**
     * Set the table for the field.
     */
    public void setTable(DatabaseTable table) {
        this.table = table;
        this.qualifiedName = null;
    }

    /**
     * Set the Java class type that corresponds to the field.
     * The JDBC type is determined from the class type,
     * this is used to optimize performance, and for binding.
     */
    @Override
    public void setType(Class type) {
        this.type = type;
        if (this.type != null && typeName == null) {
            typeName = this.type.getName();
        }
    }

    /**
     * Used for generating DDL. Set to true if the field is a unique key.
     */
    public void setUnique(boolean isUnique) {
        this.isUnique = isUnique;
    }

    /**
     * Used to specify whether the column should be included in SQL INSERT
     * statements.
     */
    public void setUpdatable(boolean isUpdatable) {
        this.isUpdatable = isUpdatable;
    }

    @Override
    public String toString() {
        return this.getQualifiedName();
    }


    public void setUseDelimiters(boolean useDelimiters) {
        this.useDelimiters = useDelimiters;
    }

    public boolean shouldUseDelimiters() {
        return this.useDelimiters;
    }

    /**
     * INTERNAL:
     * Sets the useUpperCaseForComparisons flag which is used to force using the uppercase version of the field's
     * name to determine field equality and its hashcode, but will still use the original name when writing/printing
     * operations.  If this isn't a change, it is ignored, otherwise it sets the nameForComparisons to null.
     */
    public void useUpperCaseForComparisons(boolean useUpperCaseForComparisons){
        if (this.useUpperCaseForComparisons != useUpperCaseForComparisons){
            this.useUpperCaseForComparisons = useUpperCaseForComparisons;
            this.setNameForComparisons(null);
        }
    }

    public boolean getUseUpperCaseForComparisons(){
        return this.useUpperCaseForComparisons;
    }
    /**
     * INTERNAL:
     * sets the string to be used for equality checking and determining the hashcode of this field.
     * This will overwrite the useUpperCaseForEquality setting with the passed in string.
     */
    public void setNameForComparisons(String name){
        this.nameForComparisons = name;
    }

    public boolean isCreatable() {
        return isCreatable;
    }

    public void setCreatable(boolean isCreatable) {
        this.isCreatable = isCreatable;
    }

    /**
     * INTERNAL:
     * gets the string used for comparisons and in determining the hashcode.
     */
    public String getNameForComparisons(){
        if (this.nameForComparisons == null) {
            if ((!this.useUpperCaseForComparisons) || (this.name == null)) {
                this.nameForComparisons = this.name;
            } else {
                this.nameForComparisons = this.name.toUpperCase();
            }
        }
        return this.nameForComparisons;
    }
}
