/*
 * 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.io.*;
import java.util.*;
import org.eclipse.persistence.internal.oxm.XMLObjectBuilder;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.oxm.XMLField;
import org.w3c.dom.Element;
import org.eclipse.persistence.internal.databaseaccess.Accessor;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.oxm.record.XMLRecord;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.eis.*;

/**
 * Defines the specification for a call to a JCA interaction that uses XML.
 * Builds the input and output XML records from the arguments.
 * This extends MappedInteraction to allow for mapped style of argument input and output.
 *
 * @author James
 * @since OracleAS TopLink 10<i>g</i> (10.0.3)
 */
public class XMLInteraction extends MappedInteraction {

    /** The root element name to use for the input DOM. */
    protected String inputRootElementName;

    /** The root element name to use for the output DOM. */
    protected String outputRootElementName;

    /**
     * Default constructor.
     */
    public XMLInteraction() {
        super();
        this.inputRootElementName = "";
        this.outputRootElementName = "";
    }

    /**
     * PUBLIC:
     * Return the root element name to use for the input DOM.
     */
    public String getInputRootElementName() {
        return inputRootElementName;
    }

    /**
     * PUBLIC:
     * Set the root element name to use for the input DOM.
     */
    public void setInputRootElementName(String inputRootElementName) {
        this.inputRootElementName = inputRootElementName;
    }

    /**
     * PUBLIC:
     * Return the root element name to use for the output DOM.
     */
    public String getOutputRootElementName() {
        return outputRootElementName;
    }

    /**
     * PUBLIC:
     * Set the root element name to use for the output DOM.
     */
    public void setOutputRootElementName(String outputRootElementName) {
        this.outputRootElementName = outputRootElementName;
    }

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

    /**
     * Create a DOM input record for this interaction.
     * Convert the database row or arguments into an XML DOM tree.
     */
    @Override
    public jakarta.resource.cci.Record createInputRecord(EISAccessor accessor) {
        jakarta.resource.cci.Record record = accessor.getEISPlatform().createDOMRecord(getInputRecordName(), accessor);
        Element dom = createInputDOM(accessor);
        accessor.getEISPlatform().setDOMInRecord(dom, record, this, accessor);
        if (record instanceof XMLRecord) {
          ((XMLRecord) record).setSession(this.getQuery().getSession());
        }
        return record;
    }

    /**
     * Create a DOM for this interaction.
     * Convert the database row or arguments into an XML DOM tree.
     */
    public Element createInputDOM(EISAccessor accessor) {
        Element dom = null;

        // The input record can either be build from the interaction arguments,
        // or the modify row.
        if ((getInputRow() != null) && (!hasArguments())) {
            if (getInputResultPath().length() == 0) {
                if (getInputRow() instanceof XMLRecord) {
                    dom = (Element)((XMLRecord)getInputRow()).getDOM();
                    // Rename the root element if specified to be different.
                    if (!dom.getTagName().equals(getInputRootElementName())) {
                        XMLRecord parameterRow = createXMLRecord(getInputRootElementName());
                        parameterRow.put("/" + getInputRootElementName(), getInputRow());
                        dom = (Element)parameterRow.getDOM();
                    }
                } else {
                    XMLRecord parameterRow = createXMLRecord(getInputRootElementName());
                    for (int index = 0; index < getInputRow().size(); index++) {
                        parameterRow.put(getInputRow().getFields().elementAt(index), getInputRow().getValues().elementAt(index));
                    }
                    dom = (Element)parameterRow.getDOM();
                }
            } else {
                XMLRecord parameterRow = createXMLRecord(getInputRootElementName());
                parameterRow.put(getInputResultPath(), getInputRow());
                dom = (Element)parameterRow.getDOM();
            }
        } else {
            XMLRecord parameterRow = createXMLRecord(getInputRootElementName());
            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 paramter from the row.
                if ((parameter == null) && (getInputRow() != null)) {
                    parameter = getInputRow().get(parameterName);
                }
                parameterRow.put(parameterName, parameter);
            }
            dom = (Element)parameterRow.getDOM();
        }
        return dom;
    }

    /**
     * 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 = accessor.getEISPlatform().createDatabaseRowFromDOMRecord(record, this, accessor);
        if (row == null) {
            return null;
        }
        if (getOutputResultPath().length() > 0) {
            row = (AbstractRecord)row.get(getOutputResultPath());
            // Handle the case were the output row is mapped into a database row of values.
        } else if (hasOutputArguments()) {
            row = createXMLRecord(getOutputRootElementName());
            for (int index = 0; index < getOutputArgumentNames().size(); index++) {
                DatabaseField field = (DatabaseField)getOutputArguments().get(index);
                row.put(field, row.get(getOutputArgumentNames().get(index)));
            }
        }
        return row;
    }

    /**
     * Build a collection of database rows from the Record returned from the interaction.
     */
    @Override
    public Vector buildRows(jakarta.resource.cci.Record record, EISAccessor accessor) {
        Vector rows = null;
        if (record == null) {
            return new Vector(0);
        }
        AbstractRecord row = accessor.getEISPlatform().createDatabaseRowFromDOMRecord(record, this, accessor);
        if (getOutputResultPath().length() > 0) {
            Vector values = (Vector)row.getValues(getOutputResultPath());
            if (values == null) {
                values = new Vector(0);
            }
            rows = values;
        } else {
            rows = new Vector(1);
            rows.add(row);
        }
        return rows;
    }

    /**
     * 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("\txml => ");
        Element dom = createInputDOM((EISAccessor)accessor);
        EISDOMRecord record = new EISDOMRecord(dom);
        record.transformToWriter(writer);
        return writer.toString();
    }

    /**
     * INTERNAL:
     */
    @Override
    protected DatabaseField createField(String fieldName) {
        if (getQuery().getDescriptor() != null) {
            return getQuery().getDescriptor().buildField(fieldName);
        }
        return new XMLField(fieldName);
    }

    /**
     * INTERNAL:
     * Use the createRecord method on ObjectBuilder in case the root element is namespace qualified
     */
    protected XMLRecord createXMLRecord(String rootName) {
        XMLRecord xmlRec;
        if (getQuery().getDescriptor() != null && getQuery().getDescriptor() instanceof EISDescriptor) {
            xmlRec = (XMLRecord)((XMLObjectBuilder)this.getQuery().getDescriptor().getObjectBuilder()).createRecord(getInputRootElementName(), getQuery().getSession());
        } else {
            xmlRec = new org.eclipse.persistence.oxm.record.DOMRecord(getInputRootElementName());
            xmlRec.setSession(getQuery().getSession());
        }
        return xmlRec;
    }
}
