/*
 * 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 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.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 = 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 = 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<AbstractRecord> buildRows(jakarta.resource.cci.Record record, EISAccessor accessor) {
        Vector<AbstractRecord> rows = null;
        if (record == null) {
            return new Vector<>(0);
        }
        AbstractRecord row = accessor.getEISPlatform().createDatabaseRowFromDOMRecord(record, this, accessor);
        if (getOutputResultPath().length() > 0) {
            @SuppressWarnings({"unchecked"})
            Vector<AbstractRecord> values = (Vector<AbstractRecord>)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;
    }
}
