/*
 * 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.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 that uses indexed records.
 * Builds the input and output records from the arguments.
 *
 * @author James
 * @since OracleAS TopLink 10<i>g</i> (10.0.3)
 */
public class IndexedInteraction extends EISInteraction {

    /**
     * Default constructor.
     */
    public IndexedInteraction() {
        super();
    }

    /**
     * PUBLIC:
     * Define the argument to the interaction for the index argument.
     * This must be called in the order of the arguments in the input indexed record.
     * The argumentFieldName is the field or argument name in the descriptor that maps to the indexed value.
     */
    public void addArgument(String argumentFieldName) {
        getArguments().addElement(new DatabaseField(argumentFieldName));
    }

    /**
     * PUBLIC:
     * Define the argument to the interaction for the index argument.
     * This must be called in the order of the arguments in the input indexed record.
     * The argumentValue is the value of the argument to be used to pass to the interaction.
     */
    public void addArgumentValue(Object argumentValue) {
        getArguments().addElement(argumentValue);
    }

    /**
     * PUBLIC:
     * Define the field/argument name to be substitute for the index output argument.
     * This must be called in the order of the output arguments in the result indexed record.
     * The argumentFieldName is the field or argument name in the descriptor that maps to the indexed value.
     */
    @Override
    public void addOutputArgument(String argumentFieldName) {
        getOutputArguments().addElement(new DatabaseField(argumentFieldName));
    }

    /**
     * The arguments are the values in order of occurance in the record.
     */
    @Override
    public Vector getArguments() {
        return super.getArguments();
    }

    /**
     * The output arguments in order of occurance in the record.
     */
    @Override
    public Vector<DatabaseField> getOutputArguments() {
        return super.getOutputArguments();
    }

    /**
     * The arguments are the values in order of occurance in the record.
     */
    @Override
    public void setArguments(Vector arguments) {
        super.setArguments(arguments);
    }

    /**
     * The output arguments in order of occurance in the record.
     */
    @Override
    public void setOutputArguments(Vector<DatabaseField> outputArguments) {
        super.setOutputArguments(outputArguments);
    }

    /**
     * Create an indexed 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 {
            IndexedRecord record = accessor.getRecordFactory().createIndexedRecord(getInputRecordName());
            for (int index = 0; index < getParameters().size(); index++) {
                Object parameter = getParameters().get(index);

                // Allow conversion of nested rows and collections.
                record.add(createRecordElement("", parameter, accessor));
            }
            return record;
        } catch (ResourceException exception) {
            throw EISException.resourceException(exception, accessor, null);
        }
    }

    /**
     * Build a database row from the record returned from the interaction.
     * Also handles MappedRecords for case of input being indexed but mapped ouput.
     */
    @Override
    public AbstractRecord buildRow(jakarta.resource.cci.Record record, EISAccessor accessor) {
        AbstractRecord row = null;
        if (record instanceof IndexedRecord) {
            IndexedRecord indexedRecord = (IndexedRecord)record;
            row = new DatabaseRecord(indexedRecord.size());
            for (int index = 0; index < indexedRecord.size(); index++) {
                DatabaseField field = getOutputArguments().get(index);
                row.put(field, indexedRecord.get(index));
            }
        } 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 (getOutputArgumentNames().size() == 1) {
                mappedRecord = (MappedRecord)mappedRecord.get(getOutputArgumentNames().get(0));
                // Handle the case were the output row is mapped into a database row of values.
            } else if (getOutputArgumentNames().size() > 1) {
                row = new DatabaseRecord(getOutputArgumentNames().size());
                for (int index = 0; index < getOutputArgumentNames().size(); index++) {
                    DatabaseField field = getOutputArguments().get(index);
                    row.put(field, mappedRecord.get(getOutputArgumentNames().get(index)));
                }
                return row;
            }

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