/*
 * 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.eis.interactions;

import java.io.*;
import java.util.*;
import jakarta.resource.*;
import jakarta.resource.cci.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.databaseaccess.Accessor;
import org.eclipse.persistence.internal.databaseaccess.DatasourceCall;
import org.eclipse.persistence.eis.*;

/**
 * Defines the specification for a call to a JCA interaction.
 * Builds the input and output records from the arguments.
 *
 * @author James
 * @since OracleAS TopLink 10<i>g</i> (10.0.3)
 */
public abstract class EISInteraction extends DatasourceCall {

    /** Adapter specific interaction spec. */
    protected InteractionSpec interactionSpec;

    /** Name of the function the interaction describes. */
    protected String functionName;

    /** Name to pass to the input record creation. */
    protected String inputRecordName;

    /** Adapter specific properties may be added. */
    protected Map<String, Object> properties;

    /** Holds database row of input values. */
    protected AbstractRecord inputRow;

    /** Defines the arguments to the interaction, these can be the values or argument names/fields the values come from. */
    protected Vector arguments;

    /**
     * Defines the output argument names as defined in the output record for the interaction.
     * This is shared as indexed interaction may still have mapped results.
     */
    protected Vector<String> outputArgumentNames;

    /** Defines the field values the output arguments of the interaction map to.  These are order dependent with the names. */
    protected Vector<DatabaseField> outputArguments;

    /** Path to the desired output record if nested. */
    protected String outputResultPath;

    /**
     * PUBLIC:
     * Default constructor.
     */
    protected EISInteraction() {
        super();
        this.functionName = "";
        this.inputRecordName = "";
        this.outputResultPath = "";
    }

    /**
     * PUBLIC:
     * Define the output argument to the interaction and the field/argument name to be substitute for it.
     * This is only required if an output row is not used.
     * The parameterAndArgumentFieldName is the name of the output record argument expected,
     * and is the field or argument name to be used to be used for it.
     * These names are assumed to be the same, if not this method can be called with two arguments.
     */
    public void addOutputArgument(String parameterAndArgumentFieldName) {
        addOutputArgument(parameterAndArgumentFieldName, parameterAndArgumentFieldName);
    }

    /**
     * PUBLIC:
     * Define the output argument to the interaction and the field/argument name to be substitute for it.
     * This is only required if an output row is not used.
     * The parameterName is the name of the output record argument expected.
     * The argumentFieldName is the field or argument name to be used to be used for it.
     * If these names are the same (as they normally are) this method can be called with a single argument.
     */
    public void addOutputArgument(String parameterName, String argumentFieldName) {
        getOutputArgumentNames().addElement(parameterName);
        getOutputArguments().addElement(new DatabaseField(argumentFieldName));
    }

    /**
     * The argument fields or values to the interaction that map into the input record.
     */
    public Vector getArguments() {
        // This is lazy initialized to conserv space on calls that have no parameters.
        if (arguments == null) {
            arguments = new Vector();
        }
        return arguments;
    }

    /**
     * INTERNAL:
     * The argument fields or values to the interaction that map into the input record.
     */
    public void setArguments(Vector arguments) {
        this.arguments = arguments;
    }

    /**
     * Return if argumented.
     */
    public boolean hasArguments() {
        return (arguments != null) && (!arguments.isEmpty());
    }

    @Override
    public boolean isEISInteraction() {
        return true;
    }

    /**
     * PUBLIC:
     * The output result path defines the root key for the MappedRecord that
     * the desired interaction result is nested into.
     * This is required for read interactions that need a nested record to build from the mapped object.
     */
    public String getOutputResultPath() {
        return outputResultPath;
    }

    /**
     * PUBLIC:
     * The output result path defines the root key for the MappedRecord that
     * the desired interaction result is nested into.
     * This is required for read interactions that need a nested record to build from the mapped object.
     */
    public void setOutputResultPath(String outputResultPath) {
        this.outputResultPath = outputResultPath;
    }

    /**
     * The argument names for the output record.
     */
    public Vector<String> getOutputArgumentNames() {
        // This is lazy initialized to conserv space on calls that have no parameters.
        if (outputArgumentNames == null) {
            outputArgumentNames = new Vector<>();
        }
        return outputArgumentNames;
    }

    /**
     * The argument fields to the interaction that map into the output record.
     */
    public Vector<DatabaseField> getOutputArguments() {
        // This is lazy initialized to conserv space on calls that have no parameters.
        if (outputArguments == null) {
            outputArguments = new Vector<>();
        }
        return outputArguments;
    }

    /**
     * The output arguments.
     */
    public void setOutputArguments(Vector<DatabaseField> outputArguments) {
        this.outputArguments = outputArguments;
    }

    /**
     * Set the output argument names.
     */
    public void setOutputArgumentNames(Vector<String> outputArgumentNames) {
        this.outputArgumentNames = outputArgumentNames;
    }

    /**
     * Return if argumented.
     */
    public boolean hasOutputArguments() {
        return (outputArguments != null) && (!outputArguments.isEmpty());
    }

    /**
     * Set the default record name from the descriptor.
     */
    @Override
    public void prepare(AbstractSession session) {
        if (getInputRecordName().length() == 0) {
            if ((getQuery() != null) && (getQuery().getDescriptor() instanceof EISDescriptor)) {
                EISDescriptor descriptor = (EISDescriptor)getQuery().getDescriptor();
                setInputRecordName(descriptor.getDataTypeName());
            } else {
                setInputRecordName("input");
            }
        }
        super.prepare(session);
    }

    /**
     * Create the appropriate record element for the data value.
     * If the value is a collection, create a collection of elements,
     * if the value is a map, create a nested map,
     * otherwise just return the value (primitive data).
     */
    public Object createRecordElement(String elementName, Object value, EISAccessor accessor) {
        try {
            Object element = value;

            // Handle nested collections.
            if (element instanceof List) {
                // Convert each element in the list.
                @SuppressWarnings({"unchecked"})
                List<Object> values = (List<Object>)element;
                List<Object> elements = new Vector<>(values.size());
                for (int index = 0; index < values.size(); index++) {
                    elements.add(createRecordElement(elementName, values.get(index), accessor));
                }
                element = elements;
                // Handle nested rows.
            } else if (value instanceof AbstractRecord) {
                AbstractRecord valuesRow = (AbstractRecord)value;

                // The record name for the row must be determined,
                // currently the SDK uses the table name of the row's field for this,
                // ideally this would be a property on the row.
                String recordName = elementName;
                if (valuesRow.size() > 0) {
                    recordName = valuesRow.getFields().get(0).getTableName();
                }
                MappedRecord record = accessor.getRecordFactory().createMappedRecord(recordName);
                for (Iterator<DatabaseField> keysIterator = valuesRow.getFields().iterator();
                     keysIterator.hasNext();) {
                    DatabaseField field = keysIterator.next();
                    Object elementValue = createRecordElement(field.getName(), valuesRow.get(field), accessor);
                    accessor.getEISPlatform().setValueInRecord(field.getName(), elementValue, record, accessor);
                }
                element = record;
            }
            return element;
        } catch (ResourceException exception) {
            throw EISException.resourceException(exception, accessor, null);
        }
    }

    /**
     * PUBLIC:
     * Return the JCA InteractionSpec that defines this EIS interaction.
     * The InteractionSpec is JCA adapter specific and typically
     * defines the function name.
     */
    public InteractionSpec getInteractionSpec() {
        return interactionSpec;
    }

    /**
     * PUBLIC:
     * Set the JCA InteractionSpec that defines this EIS interaction.
     * The InteractionSpec is JCA adapter specific and typically
     * defines the function name.
     */
    public void setInteractionSpec(InteractionSpec interactionSpec) {
        this.interactionSpec = interactionSpec;
    }

    /**
     * Return the string for logging purposes.
     */
    @Override
    public String getLogString(Accessor accessor) {
        StringWriter writer = new StringWriter();
        writer.write("Executing ");
        writer.write(toString());
        writer.write(Helper.cr());
        writer.write("\tspec => ");
        writer.write(String.valueOf(getInteractionSpec()));
        writer.write(Helper.cr());
        writer.write("\tproperties => ");
        writer.write(String.valueOf(getProperties()));
        writer.write(Helper.cr());
        writer.write("\tinput => [");
        if (!getParameters().isEmpty()) {
            for (Iterator<?> iterator = getParameters().iterator(); iterator.hasNext();) {
                Object parameter = iterator.next();
                writer.write(String.valueOf(parameter));
                if (iterator.hasNext()) {
                    writer.write(", ");
                } else {
                    writer.write("]");
                }
            }
        } else {
            writer.write(String.valueOf(getInputRow()));
            writer.write("]");
        }
        return writer.toString();
    }

    /**
     * Arguments to the interaction can be passed two ways.
     * The entire argument row can be converted to the input record,
     * or the arguments from the row can be translated into the interaction parameters.
     */
    @Override
    public void translate(AbstractRecord translationRow, AbstractRecord modifyRow, AbstractSession session) {
        if (modifyRow != null) {
            // Avoid clearing a prepared row.
            setInputRow(modifyRow);
        }
        if (hasArguments()) {
            List<Object> parametersValues = new ArrayList<>(getArguments().size());
            for (int index = 0; index < getArguments().size(); index++) {
                Object argument = getArguments().elementAt(index);

                // The argument is either a value or a databasefield that needs to be translated.
                if (argument instanceof DatabaseField) {
                    DatabaseField field = (DatabaseField)argument;
                    Object value = translationRow.get(field);

                    //BUG#12345:modifyRow is null for reads
                    if ((value == null) && (modifyRow != null)) {
                        value = modifyRow.get(field);
                    }
                    parametersValues.add(value);
                } else {
                    parametersValues.add(argument);
                }
            }
            setParameters(parametersValues);
        }
    }

    /**
     * Create the appropriate input record for this interaction.
     * Populate the data into the record from this interaction's arguments.
     */
    public abstract jakarta.resource.cci.Record createInputRecord(EISAccessor accessor);

    /**
     * INTERNAL:
     * Build a database row from the record returned from the interaction.
     */
    public abstract AbstractRecord buildRow(jakarta.resource.cci.Record record, EISAccessor accessor);

    /**
     * Build a collection of database rows from the Record returned from the interaction.
     * This handles IndexedRecords used as sets of result records,
     * and a single MappedRecord with a list of result records.
     */
    public Vector<AbstractRecord> buildRows(jakarta.resource.cci.Record record, EISAccessor accessor) {
        Vector<AbstractRecord> rows = null;
        if (record instanceof IndexedRecord) {
            IndexedRecord indexedRecord = (IndexedRecord)record;
            rows = new Vector<>(indexedRecord.size());
            for (int index = 0; index < indexedRecord.size(); index++) {
                Object element = indexedRecord.get(index);
                if (element instanceof jakarta.resource.cci.Record) {
                    rows.addElement(buildRow((jakarta.resource.cci.Record)element, accessor));
                } else {
                    // It is a single row record.
                    rows.add(buildRow(record, accessor));
                    return rows;
                }
            }
        } else if (record instanceof MappedRecord) {
            MappedRecord mappedRecord = (MappedRecord)record;

            // Handle the case of a single output argument of the entire row contained within the return record.
            if (getOutputResultPath().length() > 0) {
                Object element = mappedRecord.get(getOutputResultPath());

                // Handles nested rows inside an IndexedRecord, MappedRecord or List.
                if (element instanceof IndexedRecord) {
                    return buildRows((IndexedRecord)element, accessor);
                } else if (element instanceof MappedRecord) {
                    mappedRecord = (MappedRecord)element;
                } else if (element instanceof List) {
                    List<?> elements = (List<?>)element;
                    rows = new Vector<>(elements.size());
                    for (int index = 0; index < elements.size(); index++) {
                        Object elementValue = elements.get(index);
                        if (elementValue instanceof jakarta.resource.cci.Record) {
                            rows.addElement(buildRow((jakarta.resource.cci.Record)elementValue, accessor));
                        } else {
                            rows.add((AbstractRecord) elementValue);
                        }
                    }
                    return rows;
                }
            }
            rows = new Vector<>(1);
            AbstractRecord row = new EISMappedRecord(mappedRecord, accessor);
            rows.add(row);
        } else {
            rows = new Vector<>(1);
        }
        return rows;
    }

    /**
     * PUBLIC:
     * Return the function name of the interaction.
     * A function name is a common properties for a CCI InteractionSpec.
     * This cannot be generically set on the spec as it is not in the interface
     * however the EIS platform may make use of this in build the interaction spec.
     */
    public String getFunctionName() {
        return functionName;
    }

    /**
     * PUBLIC:
     * Set the function name of the interaction.
     * A function name is a common properties for a CCI InteractionSpec.
     * This cannot be generically set on the spec as it is not in the interface
     * however the EIS platform may make use of this in build the interaction spec.
     */
    public void setFunctionName(String functionName) {
        this.functionName = functionName;
    }

    /**
     * PUBLIC:
     * Return the input record name.
     * This is used as the name passed to the adapter when creating the input record.
     */
    public String getInputRecordName() {
        return inputRecordName;
    }

    /**
     * PUBLIC:
     * Set the input record name.
     * This is used as the name passed to the adapter when creating the input record.
     */
    public void setInputRecordName(String recordName) {
        this.inputRecordName = recordName;
    }

    /**
     * Returns the adapter specific properties.
     */
    public Map<String, Object> getProperties() {
        if (properties == null) {
            properties = new HashMap<>(5);
        }
        return properties;
    }

    /**
     * PUBLIC:
     * Returns the adapter property associated the given name.
     * If the interaction is associated with a query that has a descriptor,
     * The descriptor's properties are automatically inherited.
     */
    public Object getProperty(String name) {
        Object value = getProperties().get(name);

        // Check descriptor property if available.
        if ((value == null) && (getQuery() != null) && (getQuery().getDescriptor() != null)) {
            value = getQuery().getDescriptor().getProperty(name);
        }
        return value;
    }

    /**
     * Set the adapter specific properties.
     */
    public void setProperties(Map<String, Object> properties) {
        this.properties = properties;
    }

    /**
     * PUBLIC:
     * Set the adapter specific property.
     */
    public void setProperty(String name, Object value) {
        getProperties().put(name, value);
    }

    /**
     * INTERNAL:
     * Return the input database row.
     */
    public AbstractRecord getInputRow() {
        return inputRow;
    }

    /**
     * PUBLIC:
     * Set the input database row.
     */
    public void setInputRow(AbstractRecord inputRow) {
        this.inputRow = inputRow;
    }

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