/*
 * 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
//     11/19/2012-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support (foreign key metadata support)
//     11/22/2012-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support (index metadata support)
//     12/07/2012-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support (foreign key metadata support)
package org.eclipse.persistence.internal.helper;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.internal.core.helper.CoreTable;
import org.eclipse.persistence.internal.databaseaccess.*;
import org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter;
import org.eclipse.persistence.tools.schemaframework.ForeignKeyConstraint;
import org.eclipse.persistence.tools.schemaframework.IndexDefinition;

/**
 * INTERNAL:
 * <p> <b>Purpose</b>:
 * Define a fully qualified table name.<p>
 * <b>Responsibilities</b>:    <ul>
 *    <li> Allow specification of a qualifier to the table, i.e. creator or database.
 *    </ul>
 *@see DatabaseField
 */
public class DatabaseTable implements CoreTable, Cloneable, Serializable {
    protected String name;
    protected String tableQualifier;
    protected String qualifiedName;

    /** JPA 2.1 Foreign key specification data */
    protected Map<String, ForeignKeyConstraint> foreignKeyConstraints;

    /**
     * Contains the user specified unique constraints. JPA 2.0 introduced
     * the name element, therefore, if specified we will use that name
     * to create the constraint. Constraints with no name will be added to the
     * map under the null key and generated with a default name.
     * Therefore, when a name is given the list size should only ever be
     * 1. We will validate. The null key could have multiples however they will
     * have their names defaulted (as we did before).
     */
    protected Map<String, List<List<String>>> uniqueConstraints;

    /**
     * Store the set of indexes defined through meta-data for the table.
     */
    protected List<IndexDefinition> indexes;

    protected boolean useDelimiters = false;

    protected String creationSuffix;

    /**
     * Initialize the newly allocated instance of this class.
     * By default their is no qualifier.
     */
    public DatabaseTable() {
        name = "";
        tableQualifier = "";
    }

    public DatabaseTable(String possiblyQualifiedName) {
        this(possiblyQualifiedName, null, null);
    }

    public DatabaseTable(String possiblyQualifiedName, String startDelimiter, String endDelimiter) {
        setPossiblyQualifiedName(possiblyQualifiedName, startDelimiter, endDelimiter);
    }

    public DatabaseTable(String tableName, String qualifier) {
        this(tableName, qualifier, false, null, null);
    }

    public DatabaseTable(String tableName, String qualifier, boolean useDelimiters, String startDelimiter, String endDelimiter) {
        setName(tableName, startDelimiter, endDelimiter);
        this.tableQualifier = qualifier;
        this.useDelimiters = useDelimiters;
    }

    public void addForeignKeyConstraint(ForeignKeyConstraint foreignKeyConstraint) {
        if (foreignKeyConstraints == null) {
            foreignKeyConstraints = new HashMap<>();
        }

        foreignKeyConstraints.put(foreignKeyConstraint.getName(), foreignKeyConstraint);
    }

    /**
     * Add an index definition to this table.
     */
    public void addIndex(IndexDefinition index) {
        getIndexes().add(index);
    }

    /**
     * Add the unique constraint for the columns names. Used for DDL generation.
     * For now we just add all the unique constraints as we would have before
     * when we didn't have a name.
     */
    public void addUniqueConstraints(String name, List<String> columnNames) {
        if (getUniqueConstraints().containsKey(name)) {
            getUniqueConstraints().get(name).add(columnNames);
        } else {
            List<List<String>> value = new ArrayList<>();
            value.add(columnNames);
            getUniqueConstraints().put(name, value);
        }
    }

    /**
     * Return a shallow copy of the receiver.
     */
    @Override
    public DatabaseTable clone() {
        try {
            return (DatabaseTable)super.clone();
        } catch (CloneNotSupportedException exception) {
            throw new InternalError(exception.getMessage());
        }
    }

    /**
     * Two tables are equal if their names and tables are equal,
     * or their names are equal and one does not have a qualifier assigned.
     * This allows an unqualified table to equal the same fully qualified one.
     */
    @Override
    public boolean equals(Object object) {
        if (object instanceof DatabaseTable) {
            return equals((DatabaseTable)object);
        }
        return false;
    }

    /**
     * Two tables are equal if their names and tables are equal,
     * or their names are equal and one does not have a qualifier assigned.
     * This allows an unqualified table to equal the same fully qualified one.
     */
    public boolean equals(DatabaseTable table) {
        if (this == table) {
            return true;
        }
        if (table == null) {
            return false;
        }
        if (DatabasePlatform.shouldIgnoreCaseOnFieldComparisons) {
            if (this.name.equalsIgnoreCase(table.name)) {
                if ((this.tableQualifier.length() == 0) || (table.tableQualifier.length() == 0) || (this.tableQualifier.equalsIgnoreCase(table.tableQualifier))) {
                    return true;
                }
            }
        } else {
            if (this.name.equals(table.name)) {
                if ((this.tableQualifier.length() == 0) || (table.tableQualifier.length() == 0) || (this.tableQualifier.equals(table.tableQualifier))) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * returns the suffix applied to the CREATE table statement on this field for DDL generation.
     */
    public String getCreationSuffix() {
        return creationSuffix;
    }

    public ForeignKeyConstraint getForeignKeyConstraint(String name) {
        return foreignKeyConstraints.get(name);
    }

    public Map<String, ForeignKeyConstraint> getForeignKeyConstraints() {
        return foreignKeyConstraints;
    }

    /**
     * Return a list of index definitions.
     * Used for DDL generation.
     */
    public List<IndexDefinition> getIndexes() {
        if (this.indexes == null) {
            this.indexes = new ArrayList<>();
        }
        return this.indexes;
    }

    /**
     * Get method for table name.
     */
    public String getName() {
        return name;
    }

    /**
     * Get method for table name.
     */
    public String getNameDelimited(DatasourcePlatform platform) {
        if (useDelimiters){
            return platform.getStartDelimiter() + name + platform.getEndDelimiter();
        }
        return name;
    }

    public String getQualifiedName() {
        if (qualifiedName == null) {
            if (tableQualifier.equals("")) {
                qualifiedName = getName();
            } else {
                qualifiedName = getTableQualifier() + "." + getName();
            }
        }

        return qualifiedName;
    }

    public String getQualifiedNameDelimited(DatasourcePlatform platform) {
        if (tableQualifier.equals("")) {
            if (useDelimiters){
                return platform.getStartDelimiter() + getName() + platform.getEndDelimiter();
            } else {
                return getName();
            }
        } else {
            if (useDelimiters){
                return platform.getStartDelimiter() + getTableQualifier() + platform.getEndDelimiter() + "."
                  + platform.getStartDelimiter() + getName() + platform.getEndDelimiter();
            } else {
                return getTableQualifier() + "." + getName();
            }
        }
    }

    /**
     * Print the table's SQL from clause.
     */
    public void printSQL(ExpressionSQLPrinter printer) throws IOException {
        printer.getWriter().write(getQualifiedNameDelimited(printer.getPlatform()));
    }

    public String getTableQualifierDelimited(DatasourcePlatform platform) {
        if (useDelimiters && tableQualifier != null && !tableQualifier.equals("")){
            return platform.getStartDelimiter() + tableQualifier + platform.getEndDelimiter();
        }
        return tableQualifier;
    }

    public String getTableQualifier() {
        return tableQualifier;
    }

    public boolean hasUniqueConstraints() {
        return (this.uniqueConstraints != null) && (!this.uniqueConstraints.isEmpty());
    }

    public boolean hasForeignKeyConstraints() {
        return foreignKeyConstraints != null;
    }

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

    public boolean hasIndexes() {
        return (this.indexes != null) && (!this.indexes.isEmpty());
    }

    /**
     * Return a list of the unique constraints for this table.
     * Used for DDL generation.
     */
    public Map<String, List<List<String>>> getUniqueConstraints() {
        if (this.uniqueConstraints == null) {
            this.uniqueConstraints = new HashMap<>();
        }
        return this.uniqueConstraints;
    }

    /**
     * Determine whether the receiver has any identification information.
     * Return true if the name or qualifier of the receiver are nonempty.
     */
    public boolean hasName() {
        if ((getName().length() == 0) && (getTableQualifier().length() == 0)) {
            return false;
        }

        return true;
    }

    /**
     * INTERNAL:
     * Is this decorated / has an AS OF (some past time) clause.
     * <b>Example:</b>
     * SELECT ... FROM EMPLOYEE AS OF TIMESTAMP (exp) t0 ...
     */
    public boolean isDecorated() {
        return false;
    }

    protected void resetQualifiedName() {
        this.qualifiedName = null;
    }

    public void setCreationSuffix(String creationSuffix) {
        this.creationSuffix = creationSuffix;
    }

    /**
     * Set the table name.
     * Used when aliasing table names.
     */
    public void setName(String name) {
        setName(name, null, null);
    }

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

    /**
     * Used to map the project xml. Any time a string name is read from the
     * project xml, we must check if it is fully qualified and split the
     * actual name from the qualifier.
     *
     */
    public void setPossiblyQualifiedName(String possiblyQualifiedName) {
        setPossiblyQualifiedName(possiblyQualifiedName, null, null);
    }

    public void setPossiblyQualifiedName(String possiblyQualifiedName, String startDelimiter, String endDelimiter) {
        resetQualifiedName();

        int index = possiblyQualifiedName.lastIndexOf('.');

        if (index == -1) {
            setName(possiblyQualifiedName, startDelimiter, endDelimiter);
            this.tableQualifier = "";
        } else {
            setName(possiblyQualifiedName.substring(index + 1, possiblyQualifiedName.length()), startDelimiter, endDelimiter);
            setTableQualifier(possiblyQualifiedName.substring(0, index), startDelimiter, endDelimiter);

            if((startDelimiter != null) && possiblyQualifiedName.startsWith(startDelimiter) && (endDelimiter != null) && possiblyQualifiedName.endsWith(endDelimiter)) {
                // It's 'Qualifier.Name' - it should be treated as a single string.
                // Would that be 'Qualifier'.'Name' both setName and setTableQualifier methods would have set useDelimeters to true.
                if(!this.useDelimiters) {
                    setName(possiblyQualifiedName);
                    this.tableQualifier = "";
                }
            }
        }
    }

    public void setTableQualifier(String qualifier) {
        setTableQualifier(qualifier, null, null);
    }

    public void setTableQualifier(String qualifier, String startDelimiter, String endDelimiter) {
        if ((startDelimiter != null) && (endDelimiter != null) && !startDelimiter.equals("")&& !endDelimiter.equals("") && qualifier.startsWith(startDelimiter) && qualifier.endsWith(endDelimiter)){
            this.tableQualifier = qualifier.substring(startDelimiter.length(), qualifier.length() - endDelimiter.length());
            useDelimiters = true;
        } else {
            this.tableQualifier = qualifier;
        }
        resetQualifiedName();
    }

    @Override
    public String toString() {
        return "DatabaseTable(" + getQualifiedName() + ")";
    }

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

    public boolean shouldUseDelimiters() {
        return useDelimiters;
    }
}
