/*
 * 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
package org.eclipse.persistence.tools.schemaframework;

import java.io.IOException;
import java.io.Serializable;
import java.io.Writer;

import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.internal.databaseaccess.FieldTypeDefinition;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.logging.SessionLog;

/**
 * <p>
 * <b>Purpose</b>: Define a database field definition for creation within a table.
 * This differs from DatabaseField in that it is used only table creation not a runtime.
 * <p>
 * <b>Responsibilities</b>:
 * <ul>
 * <li> Store the name, java type, size and sub-size.
 * The sizes are optional and the name of the java class is used for the type.
 * </ul>
 */
public class FieldDefinition implements Serializable, Cloneable {
    protected String name;
    /**
     * Java type class for the field.
     * Particular database type is generated based on platform from this.
     */
    protected Class<?> type;
    /**
     * Generic database type name for the field, which can be used instead of the Java class 'type'.
     * This is translated to a particular database type based on platform.
     */
    protected String typeName;
    /**
     * DatabaseField stores the field name with case and delimiting information.
     * Used if the field needs to be found in the table metadata, for extending tables.
     * if null, name is used for comparison to determine if this field already exists.
     */
    protected DatabaseField field;
    /**
     * Database-specific complete type definition like "VARCHAR2(50) UNIQUE NOT NULL".
     * If this is given, other additional type constraint fields(size, unique, null) are meaningless.
     */
    protected String typeDefinition;
    protected int size;
    protected int subSize;
    protected boolean shouldAllowNull;
    protected boolean isIdentity;
    protected boolean isPrimaryKey;
    protected boolean isUnique;
    protected String additional;
    protected String constraint;
    protected String foreignKeyFieldName;

    public FieldDefinition() {
        this.name = "";
        this.size = 0;
        this.subSize = 0;
        this.shouldAllowNull = true;
        this.isIdentity = false;
        this.isPrimaryKey = false;
        this.isUnique = false;
    }

    public FieldDefinition(String name, Class<?> type) {
        this.name = name;
        this.type = type;
        this.size = 0;
        this.subSize = 0;
        shouldAllowNull = true;
        isIdentity = false;
        isPrimaryKey = false;
        isUnique = false;
    }

    public FieldDefinition(String name, Class<?> type, int size) {
        this();
        this.name = name;
        this.type = type;
        this.size = size;
    }

    public FieldDefinition(String name, Class<?> type, int size, int subSize) {
        this();
        this.name = name;
        this.type = type;
        this.size = size;
        this.subSize = subSize;
    }

    public FieldDefinition(String name, String typeName) {
        this();
        this.name = name;
        this.typeName = typeName;
    }

    /**
     * INTERNAL:
     * Append the database field definition string to the table creation statement.
     * @param writer  Target writer where to write field definition string.
     * @param session Current session context.
     * @param table   Database table being processed.
     * @throws ValidationException When invalid or inconsistent data were found.
     */
    public void appendDBString(final Writer writer, final AbstractSession session,
            final TableDefinition table) throws ValidationException {
        try {
            writer.write(name);
            writer.write(" ");

            if (getTypeDefinition() != null) { //apply user-defined complete type definition
                writer.write(typeDefinition);

            } else {
                final DatabasePlatform platform = session.getPlatform();
                // compose type definition - type name, size, unique, identity, constraints...
                final FieldTypeDefinition fieldType
                        = DatabaseObjectDefinition.getFieldTypeDefinition(platform, type, typeName);

                String qualifiedName = table.getFullName() + '.' + name;
                boolean shouldPrintFieldIdentityClause = isIdentity && platform.shouldPrintFieldIdentityClause(session, qualifiedName);
                platform.printFieldTypeSize(writer, this, fieldType, shouldPrintFieldIdentityClause);

                if (shouldPrintFieldIdentityClause) {
                    platform.printFieldIdentityClause(writer);
                }
                if (shouldAllowNull && fieldType.shouldAllowNull()) {
                    platform.printFieldNullClause(writer);
                } else {
                    platform.printFieldNotNullClause(writer);
                }
                if (isUnique) {
                    if (platform.supportsUniqueColumns()) {
                        // #282751: do not add UNIQUE if the field is also simple primary key
                        if (!isPrimaryKey || table.getPrimaryKeyFieldNames().size() > 1) {
                            platform.printFieldUnique(writer, shouldPrintFieldIdentityClause);
                        } else {
                            setUnique(false);
                            session.log(SessionLog.WARNING, SessionLog.DDL, "removing_unique_constraint", qualifiedName);
                        }
                    } else {
                        // Need to move the unique column to be a constraint.
                        setUnique(false);
                        String constraintName = table.buildUniqueKeyConstraintName(table.getName(), table.getFields().indexOf(this), platform.getMaxUniqueKeyNameSize());
                        table.addUniqueKeyConstraint(constraintName, name);
                    }
                }
                if (constraint != null) {
                    writer.write(" " + constraint);
                }
                if (additional != null) {
                    writer.write(" " + additional);
                }
            }
        } catch (IOException ioException) {
            throw ValidationException.fileError(ioException);
        }
    }

    /**
     * INTERNAL:
     * Append the database field definition string to the type creation statement.
     * Types do not support constraints.
     * @param writer  Target writer where to write field definition string.
     * @param session Current session context.
     * @throws ValidationException When invalid or inconsistent data were found.
     */
    public void appendTypeString(final Writer writer, final AbstractSession session)
            throws ValidationException {
        final FieldTypeDefinition fieldType
                = DatabaseObjectDefinition.getFieldTypeDefinition(session, type, typeName);
        try {
            writer.write(name);
            writer.write(" ");
            writer.write(fieldType.getName());
            if ((fieldType.isSizeAllowed()) && ((size != 0) || (fieldType.isSizeRequired()))) {
                writer.write("(");
                if (size == 0) {
                    writer.write(Integer.toString(fieldType.getDefaultSize()));
                } else {
                    writer.write(Integer.toString(size));
                }
                if (subSize != 0) {
                    writer.write(",");
                    writer.write(Integer.toString(subSize));
                } else if (fieldType.getDefaultSubSize() != 0) {
                    writer.write(",");
                    writer.write(Integer.toString(fieldType.getDefaultSubSize()));
                }
                writer.write(")");
            }
            if (additional != null) {
                writer.write(" " + additional);
            }
        } catch (IOException ioException) {
            throw ValidationException.fileError(ioException);
        }
    }

    /**
     * PUBLIC:
     */
    @Override
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException impossible) {
            return null;
        }
    }

    /**
     * PUBLIC:
     * Return any additional information about this field to be given when the table is created.
     */
    public String getAdditional() {
        return additional;
    }

    /**
     * PUBLIC:
     * Return any constraint of this field.
     * i.e. "BETWEEN 0 AND 1000000".
     */
    public String getConstraint() {
        return constraint;
    }

    public String getForeignKeyFieldName() {
        return foreignKeyFieldName;
    }

    /**
     * PUBLIC:
     * Return the name of the field.
     */
    public String getName() {
        return name;
    }

    /**
     * INTERNAL:
     * Return the databasefield.
     */
    public DatabaseField getDatabaseField() {
        return field;
    }

    /**
     * PUBLIC:
     * Return the size of the field, this is only required for some field types.
     */
    public int getSize() {
        return size;
    }

    /**
     * PUBLIC:
     * Return the sub-size of the field.
     * This is used as the decimal precision for numeric values only.
     */
    public int getSubSize() {
        return subSize;
    }

    /**
     * PUBLIC:
     * Return the type of the field.
     * This should be set to a java class, such as String.class, Integer.class or Date.class.
     */
    public Class<?> getType() {
        return type;
    }

    /**
     * PUBLIC:
     * Return the type name of the field.
     * This is the generic database type name, which can be used instead of the Java class 'type'.
     * This is translated to a particular database type based on platform.
     */
    public String getTypeName() {
        return typeName;
    }

    /**
     * PUBLIC:
     * Return the type definition of the field.
     * This is database-specific complete type definition like "VARCHAR2(50) UNIQUE NOT NULL".
     * If this is given, other additional type constraint fields(size, unique, null) are meaningless.
     */
    public String getTypeDefinition() {
        return typeDefinition;
    }

    /**
     * PUBLIC:
     * Answer whether the receiver is an identity field.
     * Identity fields are Sybase specific,
     * they insure that on insert a unique sequential value is stored in the row.
     */
    public boolean isIdentity() {
        return isIdentity;
    }

    /**
     * PUBLIC:
     * Answer whether the receiver is a primary key.
     * If the table has a multipart primary key this should be set in each field.
     */
    public boolean isPrimaryKey() {
        return isPrimaryKey;
    }

    /**
     * PUBLIC:
     * Answer whether the receiver is a unique constraint field.
     */
    public boolean isUnique() {
        return isUnique;
    }

    /**
     * PUBLIC:
     * Set any additional information about this field to be given when the table is created.
     */
    public void setAdditional(String string) {
        additional = string;
    }

    /**
     * PUBLIC:
     * Set any constraint of this field.
     * i.e. "BETWEEN 0 AND 1000000".
     */
    public void setConstraint(String string) {
        constraint = string;
    }

    public void setForeignKeyFieldName(String foreignKeyFieldName) {
        this.foreignKeyFieldName = foreignKeyFieldName;
    }

    /**
     * PUBLIC:
     * Set whether the receiver is an identity field.
     * Identity fields are Sybase specific,
     * they insure that on insert a unique sequential value is stored in the row.
     */
    public void setIsIdentity(boolean value) {
        isIdentity = value;
        if (value) {
            setShouldAllowNull(false);
        }
    }

    /**
     * PUBLIC:
     * Set whether the receiver is a primary key.
     * If the table has a multipart primary key this should be set in each field.
     */
    public void setIsPrimaryKey(boolean value) {
        isPrimaryKey = value;
        if (value) {
            setShouldAllowNull(false);
        }
    }

    /**
     * PUBLIC:
     * Set the name of the field.
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * INTERNAL:
     * Set the DatabaseField that is associated to this FieldDefinition object.
     * The databaesField is used when extending tables to see if this field already exists.
     */
    public void setDatabaseField(DatabaseField field) {
        this.field = field;
    }

    /**
     * PUBLIC:
     * Set whether the receiver should allow null values.
     */
    public void setShouldAllowNull(boolean value) {
        shouldAllowNull = value;
    }

    /**
     * PUBLIC:
     * Set the size of the field, this is only required for some field types.
     */
    public void setSize(int size) {
        this.size = size;
    }

    /**
     * PUBLIC:
     * Set the sub-size of the field.
     * This is used as the decimal precision for numeric values only.
     */
    public void setSubSize(int subSize) {
        this.subSize = subSize;
    }

    /**
     * PUBLIC:
     * Set the type of the field.
     * This should be set to a java class, such as String.class, Integer.class or Date.class.
     */
    public void setType(Class<?> type) {
        this.type = type;
    }

    /**
     * PUBLIC:
     * Set the type name of the field.
     * This is the generic database type name, which can be used instead of the Java class 'type'.
     * This is translated to a particular database type based on platform.
     */
    public void setTypeName(String typeName) {
        this.typeName = typeName;
    }

    /**
     * PUBLIC:
     * Set the type definition of the field.
     * This is database-specific complete type definition like "VARCHAR2(50) UNIQUE NOT NULL".
     * If this is given, other additional type constraint fields(size, unique, null) are meaningless.
     */
    public void setTypeDefinition(String typeDefinition) {
        this.typeDefinition = typeDefinition;
    }

    /**
     * PUBLIC:
     * Set whether the receiver is a unique constraint field.
     */
    public void setUnique(boolean value) {
        isUnique = value;
    }

    /**
     * PUBLIC:
     * Return whether the receiver should allow null values.
     */
    public boolean shouldAllowNull() {
        return shouldAllowNull;
    }

    @Override
    public String toString() {
        return Helper.getShortClassName(getClass()) + "(" + getName() + "(" + getType() + "))";
    }
}
