/*
 * 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
//     14/05/2012-2.4 Guy Pelletier
//       - 376603: Provide for table per tenant support for multitenant applications
package org.eclipse.persistence.mappings.structures;

import java.sql.Array;
import java.sql.Ref;
import java.sql.Struct;
import java.sql.Types;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.RelationalDescriptor;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.internal.expressions.SQLSelectStatement;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.queries.ReadObjectQuery;
import org.eclipse.persistence.queries.ValueReadQuery;
import org.eclipse.persistence.sessions.DatabaseRecord;

/**
 * <p><b>Purpose:</b>
 * Differentiates object-relational descriptors from normal relational descriptors.
 * The object-relational descriptor describes a type not a table, (although there
 * is normally a table associated with the type, unless it is aggregate).
 */
@SuppressWarnings("unchecked")
public class ObjectRelationalDataTypeDescriptor extends RelationalDescriptor {
    protected String structureName;
    protected Vector orderedFields;
    protected Vector allOrderedFields;

    public ObjectRelationalDataTypeDescriptor() {
        this.orderedFields = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance();
    }

    /**
     * INTERNAL:
     * Auto-Default orderedFields to fields
     */
    @Override
    public void initialize(AbstractSession session) throws DescriptorException {
        super.initialize(session);
        if (orderedFields==null || orderedFields.size()==0){
           orderedFields=getAllFields();
        }
        setAllOrderedFields();
    }


    /**
     * PUBLIC:
     * Order the fields in a specific
     * Add the field ordering, this will order the fields in the order this method is called.
     * @param fieldName the name of the field to add ordering on.
     */
    public void addFieldOrdering(String fieldName) {
        getOrderedFields().addElement(new DatabaseField(fieldName));
    }

    /**
     * INTERNAL:
     * Extract the direct values from the specified field value.
     * Return them in a vector.
     * The field value better be an Array.
     */
    @Override
    public Vector buildDirectValuesFromFieldValue(Object fieldValue) throws DatabaseException {

        if(fieldValue == null) {
            return null;
        }

        return Helper.vectorFromArray((Object[])fieldValue);
    }

    /**
     * INTERNAL:
     * Build the appropriate field value for the specified
     * set of direct values.
     * The database better be expecting an ARRAY.
     */
    @Override
    public Object buildFieldValueFromDirectValues(Vector directValues, String elementDataTypeName, AbstractSession session) throws DatabaseException {
        Object[] fields = Helper.arrayFromVector(directValues);
        try {
            session.getAccessor().incrementCallCount(session);
            java.sql.Connection connection = session.getAccessor().getConnection();
            return session.getPlatform().createArray(elementDataTypeName, fields, session,connection);
        } catch (java.sql.SQLException ex) {
            throw DatabaseException.sqlException(ex, session, false);
        } finally {
            session.getAccessor().decrementCallCount();
        }
    }

    /**
     * INTERNAL:
     * Build and return the field value from the specified nested database row.
     * The database better be expecting a Struct.
     */
    @Override
    public Object buildFieldValueFromNestedRow(AbstractRecord nestedRow, AbstractSession session) throws DatabaseException {
        java.sql.Connection connection = session.getAccessor().getConnection();
        return this.buildStructureFromRow(nestedRow, session, connection);
    }

    /**
     * INTERNAL:
     * Build and return the appropriate field value for the specified
     * set of nested rows.
     * The database better be expecting an ARRAY.
     * It looks like we can ignore inheritance here....
     */
    @Override
    public Object buildFieldValueFromNestedRows(Vector nestedRows, String structureName, AbstractSession session) throws DatabaseException {
        Object[] fields = new Object[nestedRows.size()];
        java.sql.Connection connection = session.getAccessor().getConnection();
        boolean reconnected = false;

        try {
            if (connection == null) {
                session.getAccessor().incrementCallCount(session);
                reconnected = true;
                connection = session.getAccessor().getConnection();
            }

            int i = 0;
            for (Enumeration stream = nestedRows.elements(); stream.hasMoreElements();) {
                AbstractRecord nestedRow = (AbstractRecord)stream.nextElement();
                fields[i++] = this.buildStructureFromRow(nestedRow, session, connection);
            }

            return session.getPlatform().createArray(structureName, fields, session,connection);
        } catch (java.sql.SQLException exception) {
            throw DatabaseException.sqlException(exception, session, false);
        } finally {
            if (reconnected) {
                session.getAccessor().decrementCallCount();
            }
        }
    }

     /**
      * INTERNAL:
      * Build and return the nested rows from the specified field value.
      * This method allows the field value to  be an ARRAY containing other structures
      * such as arrays or Struct, or direct values.
      */
     static public Object buildContainerFromArray(Array fieldValue, ObjectRelationalDatabaseField arrayField, AbstractSession session) throws DatabaseException {
        if (arrayField.getType()==null){
            return fieldValue;
        }
        Object[] objects = null;
        try {
            objects = (Object[])fieldValue.getArray();
        } catch (java.sql.SQLException ex) {
            throw DatabaseException.sqlException(ex, session, false);
        }
        if (objects == null) {
            return null;
        }

        boolean isNestedStructure = false;
        ObjectRelationalDataTypeDescriptor ord=null;
        DatabaseField nestedType = null;
        nestedType = arrayField.getNestedTypeField();
        if ((nestedType != null) && nestedType.getSqlType()==Types.STRUCT){
            ClassDescriptor descriptor = session.getDescriptor(nestedType.getType());
            if ((descriptor != null) && (descriptor.isObjectRelationalDataTypeDescriptor())) {
                //this is used to convert non-null objects passed through stored procedures and custom SQL to structs
                ord=(ObjectRelationalDataTypeDescriptor)descriptor;
            }
        } else if ((nestedType != null) && (nestedType instanceof ObjectRelationalDatabaseField) ){
            isNestedStructure = true;
        }
        //handle ARRAY conversions
        ReadObjectQuery query = new ReadObjectQuery();
        query.setSession(session);
        ContainerPolicy cp = ContainerPolicy.buildPolicyFor(arrayField.getType());
        Object container = cp.containerInstance(objects.length);
        for (int i = 0; i < objects.length; i++) {
            Object arrayValue = objects[i];
            if (arrayValue == null) {
                return null;
            }
            if (ord!=null){
                AbstractRecord nestedRow = ord.buildRowFromStructure( (Struct)arrayValue);
                ClassDescriptor descriptor = ord;
                if (descriptor.hasInheritance()) {
                    Class newElementClass = descriptor.getInheritancePolicy().classFromRow(nestedRow, session);
                    if (!descriptor.getJavaClass().equals(newElementClass)) {
                        descriptor = session.getDescriptor(newElementClass);
                        if (descriptor==null){
                            descriptor=ord;
                        }
                    }
                }
                arrayValue = descriptor.getObjectBuilder().buildNewInstance();
                descriptor.getObjectBuilder().buildAttributesIntoObject(arrayValue, null, nestedRow, query, null, null, false, session);
            } else if (isNestedStructure && (arrayValue instanceof Array)){
                arrayValue = buildContainerFromArray((Array)arrayValue, (ObjectRelationalDatabaseField)nestedType, session);
            }

            cp.addInto(arrayValue, container, session);
        }
        return container;
     }

    /**
     * INTERNAL:
     * Build and return the nested database row from the specified field value.
     * The field value better be an Struct.
     */
     @Override
    public AbstractRecord buildNestedRowFromFieldValue(Object fieldValue) throws DatabaseException {

        AbstractRecord row = new DatabaseRecord();
        Object[] attributes = (Object[])fieldValue;

        for (int index = 0; index < getAllOrderedFields().size(); index++) {
            DatabaseField field = (DatabaseField) getAllOrderedFields().get(index);
            row.put(field, attributes[index]);
        }

        return row;
    }

    /**
     * INTERNAL:
     * Creates allOrderedFields Vector, keeping allFields contents ordered.
     */
    private void setAllOrderedFields() {
        allOrderedFields = new Vector(orderedFields.size());
        Vector<DatabaseField> allFieldsCopy = new Vector(getAllFields());
        for (DatabaseField orderedField : (Vector<DatabaseField>) getOrderedFields()) {
            Iterator<DatabaseField> iterator = allFieldsCopy.iterator();
            while (iterator.hasNext()) {
                DatabaseField field = iterator.next();
                if (orderedField.getName().equalsIgnoreCase(field.getName())) {
                    allOrderedFields.add(field);
                    iterator.remove();
                }
            }
        }
    }

    /**
     * INTERNAL:
     * Build and return the nested rows from the specified field value.
     * The field value better be an ARRAY.
     */
    @Override
    public Vector buildNestedRowsFromFieldValue(Object fieldValue, AbstractSession session) throws DatabaseException {

        if(fieldValue==null){
            return null;
        }

        Object[] structs = (Object[])fieldValue;

        Vector nestedRows = new Vector(structs.length);
        for (int i = 0; i < structs.length; i++) {
            Object[] struct = (Object[])structs[i];
            if (struct == null) {
                return null;
            }
            nestedRows.addElement(this.buildNestedRowFromFieldValue(struct));
        }
        return nestedRows;
    }

    /**
     * INTERNAL:
     * Build a row representation from the ADT structure field array.
     * TopLink will then build the object from the row.
     */
    public AbstractRecord buildRowFromStructure(Struct structure) throws DatabaseException {
        Object[] attributes;
        try {
            attributes = structure.getAttributes();
        } catch (java.sql.SQLException exception) {
            throw DatabaseException.sqlException(exception);
        }

        if(attributes!=null){
            for(int i=0;i<attributes.length;i++){
                if(attributes[i] instanceof Array ){
                    attributes[i]=ObjectRelationalDataTypeDescriptor.buildArrayObjectFromArray(attributes[i]);
                }else if(attributes[i] instanceof Struct){
                    attributes[i]=ObjectRelationalDataTypeDescriptor.buildArrayObjectFromStruct(attributes[i]);
                }
            }
        }

        return buildNestedRowFromFieldValue(attributes);
    }

    /**
     * INTERNAL:
     * Build a ADT structure from the row data.
     */
    public Struct buildStructureFromRow(AbstractRecord row, AbstractSession session, java.sql.Connection connection) throws DatabaseException {
        Struct structure;
        boolean reconnected = false;

        try {
            if (connection == null) {
                session.getAccessor().incrementCallCount(session);
                reconnected = true;
                connection = session.getAccessor().getConnection();
            }

            Object[] fields = new Object[getOrderedFields().size()];
            for (int index = 0; index < getOrderedFields().size(); index++) {
                DatabaseField field = (DatabaseField)getOrderedFields().elementAt(index);
                fields[index] = row.get(field);
            }

            structure = session.getPlatform().createStruct(getStructureName(), fields, row, getOrderedFields(), session, connection);
        } catch (java.sql.SQLException exception) {
            throw DatabaseException.sqlException(exception, session, false);
        } finally {
            if (reconnected) {
                session.getAccessor().decrementCallCount();
            }
        }

        return structure;
    }

    /**
     * INTERNAL:
     * Build array of objects for Array data type.
     */
    public static Object buildArrayObjectFromArray(Object array) throws DatabaseException {
        Object[] objects = null;
        if(array==null){
            return array;
        }
        try {
            objects = (Object[])((Array)array).getArray();
        } catch (java.sql.SQLException ex) {
            throw DatabaseException.sqlException(ex);
        }
        if (objects == null ) {
            return null;
        } else {
            for (int i=0;i<objects.length;i++){
                if (objects[i] instanceof Array){
                    objects[i] = buildArrayObjectFromArray(objects[i]);
                }
                if (objects[i] instanceof Struct){
                    objects[i] = buildArrayObjectFromStruct(objects[i]);
                }
            }
        }
        return objects;
    }

    /**
     * INTERNAL:
     * Build array of objects for Struct data type.
     */
    public static Object buildArrayObjectFromStruct(Object structure) throws DatabaseException{
        Object[] attributes = null;
        if(structure==null){
            return structure;
        }
        try {
            attributes = ((Struct)structure).getAttributes();
        } catch (java.sql.SQLException exception) {
            throw DatabaseException.sqlException(exception);
        }
        if (attributes==null){
            return null;
        } else {
            for(int i=0;i<attributes.length;i++){
                if (attributes[i] instanceof Array){
                    attributes[i] = buildArrayObjectFromArray(attributes[i]);
                }
                if (attributes[i] instanceof Struct){
                    attributes[i] = buildArrayObjectFromStruct(attributes[i]);
                }
            }
        }
        return attributes;
    }

    /**
     * INTERNAL:
     * Aggregates use a dummy table as default.
     */
    @Override
    protected DatabaseTable extractDefaultTable() {
        if (isAggregateDescriptor()) {
            return new DatabaseTable();
        }

        return super.extractDefaultTable();
    }

    /**
     * INTERNAL:
     * Return the field order.
     */
    public Vector getOrderedFields() {
        return orderedFields;
    }

    /**
     * INTERNAL:
     * Return allFields contents ordered.
     */
    private Vector getAllOrderedFields() {
        return allOrderedFields;
    }

    /**
     * INTERNAL:
     * Get the ref for the object.
     * This is required for use by Refs, there might be a better way to do it when objID are supported.
     * (i.e. getting it from the object or identity map).
     */
    public Ref getRef(Object object, AbstractSession session) {
        SQLSelectStatement statement = new SQLSelectStatement();
        statement.addTable(getTables().firstElement());// Assumed only one for obj-rel descriptors.
        statement.getFields().addElement(new org.eclipse.persistence.expressions.ExpressionBuilder().ref());
        statement.setWhereClause(getObjectBuilder().buildPrimaryKeyExpressionFromObject(object, session));
        statement.setRequiresAliases(true);
        statement.normalize(session, this);

        ValueReadQuery valueQuery = new ValueReadQuery();
        valueQuery.setSQLStatement(statement);
        valueQuery.checkPrepare(session, new DatabaseRecord(), true);
        // Must return unwrapped Ref on WLS.
        valueQuery.getCall().setIsNativeConnectionRequired(true);

        Ref ref = (Ref)session.executeQuery(valueQuery);

        return ref;
    }

    /**
     * PUBLIC:
     * Return the name of the structure.
     * This is the name of the user defined data type as defined on the database.
     */
    public String getStructureName() {
        return structureName;
    }

    /**
     *  PUBLIC:
     *  Return if this is an ObjectRelationalDataTypeDescriptor.
     */
    @Override
    public boolean isObjectRelationalDataTypeDescriptor(){
        return true;
    }

    /**
     * INTERNAL:
     * Aggregates obj-rel are initialized normally as no cloning is required.
     */
    @Override
    public boolean requiresInitialization(AbstractSession session) {
        return true;
    }

    @Override
    protected void validateMappingType(DatabaseMapping mapping) {
        //do nothing
    }

    /**
     * INTERNAL:
     * Set the field order.
     */
    public void setOrderedFields(Vector orderedFields) {
        this.orderedFields = orderedFields;
    }

    /**
     * PUBLIC:
     * Set the name of the structure.
     * This is the name of the user defined data type as defined on the database.
     */
    public void setStructureName(String structureName) {
        this.structureName = structureName;
    }
}
