/*
 * Copyright (c) 1998, 2020 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.util.*;
import jakarta.resource.*;
import jakarta.resource.cci.*;

import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.sessions.DatabaseRecord;
import org.eclipse.persistence.eis.*;

/**
 * Defines the specification for a call to a JCA interaction using Mapped records.
 * Builds the input and output records from the arguments.
 *
 * @author James
 * @since OracleAS TopLink 10<i>g</i> (10.0.3)
 */
public class MappedInteraction extends EISInteraction {
    protected String inputResultPath;
    protected Vector argumentNames;

    /**
     * Default constructor.
     */
    public MappedInteraction() {
        super();
        this.inputResultPath = "";
    }

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

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

    /**
     * PUBLIC:
     * Define the argument to the interaction and the value name to be input for it.
     * This is only required if an input row is not used.
     * The parameterName is the name of the input record argument.
     * The argumentValue is the value of the input record argument.
     */
    public void addArgumentValue(String parameterName, Object argumentValue) {
        getArgumentNames().addElement(parameterName);
        getArguments().addElement(argumentValue);
    }

    /**
     * PUBLIC:
     * The input result path defines the root key for the MappedRecord that
     * the interaction argument is nested into.
     * This is required for write interaction that take the row build from the mapped object
     * and need the input to contain that row record as part of the input, instead of the entire input.
     */
    public String getInputResultPath() {
        return inputResultPath;
    }

    /**
     * PUBLIC:
     * The input result path defines the root key for the MappedRecord that
     * the interaction argument is nested into.
     * This is required for write interaction that take the row build from the mapped object
     * and need the input to contain that row record as part of the input, instead of the entire input.
     */
    public void setInputResultPath(String inputResultPath) {
        this.inputResultPath = inputResultPath;
    }

    /**
     * The argument names for the input record.
     */
    public Vector getArgumentNames() {
        // This is lazy initialized to conserv space on calls that have no parameters.
        if (argumentNames == null) {
            argumentNames = new Vector();
        }
        return argumentNames;
    }

    /**
     * INTERNAL:
     * The argument names for the input record.
     */
    public void setArgumentNames(Vector argumentNames) {
        this.argumentNames = argumentNames;
    }

    /**
     * Create a mapped input record for this interaction.
     * Populate the data into the record from this interaction's arguments.
     */
    @Override
    public jakarta.resource.cci.Record createInputRecord(EISAccessor accessor) {
        try {
            MappedRecord record = null;

            // The input record can either be build from the interaction arguments,
            // or the modify row.
            if ((getInputRow() != null) && (!hasArguments())) {
                if (getInputResultPath().length() == 0) {
                    record = (MappedRecord)createRecordElement(getInputRecordName(), getInputRow(), accessor);
                } else {
                    record = accessor.getRecordFactory().createMappedRecord(getInputRecordName());
                    Object nestedRecord = createRecordElement(getInputResultPath(), getInputRow(), accessor);
                    accessor.getEISPlatform().setValueInRecord(getInputResultPath(), nestedRecord, record, accessor);
                }
            } else {
                record = accessor.getRecordFactory().createMappedRecord(getInputRecordName());
                for (int index = 0; index < getArgumentNames().size(); index++) {
                    String parameterName = (String)getArgumentNames().get(index);
                    Object parameter = getParameters().get(index);

                    // If no arguments were passed to the call execution find the parameter from the row.
                    if ((parameter == null) && (getInputRow() != null)) {
                        parameter = getInputRow().get(parameterName);
                    }

                    // Allow for conversion of nested rows into nested records.
                    parameter = createRecordElement(parameterName, parameter, accessor);
                    // Allow for the platform to perform any platform specific record access.
                    accessor.getEISPlatform().setValueInRecord(parameterName, parameter, record, accessor);
                }
            }
            return record;
        } catch (ResourceException exception) {
            throw EISException.resourceException(exception, accessor, null);
        }
    }

    /**
     * Create a mapped input record for this interaction.
     * Populate the data into the record from this interaction's translation row.
     */
    public jakarta.resource.cci.Record createTranslationRecord(AbstractRecord transaltionRow, EISAccessor accessor) {
        return (MappedRecord)createRecordElement(getInputRecordName(), transaltionRow, accessor);
    }

    /**
     * Build a database row from the record returned from the interaction.
     */
    @Override
    public AbstractRecord buildRow(jakarta.resource.cci.Record record, EISAccessor accessor) {
        if (record == null) {
            return  null;
        }
        AbstractRecord row = null;

        if (record instanceof IndexedRecord) {
            IndexedRecord indexedRecord = (IndexedRecord)record;
            if (indexedRecord.isEmpty()) {
                return null;
            }
            if (indexedRecord.get(0) instanceof jakarta.resource.cci.Record) {
                return buildRow((jakarta.resource.cci.Record)indexedRecord.get(0), accessor);
            }
        }
        // If not a mapped record then just put it as a result value in the row.
        if (!(record instanceof MappedRecord)) {
            row = new DatabaseRecord(1);
            row.put(getOutputResultPath(), record);
            return row;
        }
        MappedRecord mappedRecord = (MappedRecord)record;

        // The desired result is either the entire output record,
        // or a translation of the output with the output arguments.
        if (hasOutputArguments()) {
            row = new DatabaseRecord(getOutputArgumentNames().size());
            for (int index = 0; index < getOutputArgumentNames().size(); index++) {
                DatabaseField field = (DatabaseField)getOutputArguments().get(index);
                row.put(field, mappedRecord.get(getOutputArgumentNames().get(index)));
            }
            return row;
        } else if (getOutputResultPath().length() > 0) {
            // Extract the desired nested record from the output.
            mappedRecord = (MappedRecord)mappedRecord.get(getOutputResultPath());
        }

        // Wrapped the record in a database to avoid lossing any information in conversion to database row,
        // also gets around problem of some adatpers not supporting keySet or entrySet.
        row = new EISMappedRecord(mappedRecord, accessor);
        return row;
    }
}
