/*
 * 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.internal.eis.adapters.xmlfile;

import java.io.File;
import java.util.List;

import jakarta.resource.ResourceException;
import jakarta.resource.cci.Connection;
import jakarta.resource.cci.Interaction;
import jakarta.resource.cci.InteractionSpec;
import jakarta.resource.cci.Record;
import jakarta.resource.cci.ResourceWarning;

import org.eclipse.persistence.eis.EISDOMRecord;
import org.eclipse.persistence.eis.EISException;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.oxm.XMLField;

/**
 * Interaction to XML file JCA adapter.
 * Executes the interaction spec against the file and DOM.
 *
 * @author James
 * @since OracleAS TopLink 10<i>g</i> (10.0.3)
 */
public class XMLFileInteraction implements Interaction {

    /** Store the connection the interaction was created from. */
    protected XMLFileConnection connection;

    /**
     * Default constructor.
     */
    public XMLFileInteraction(XMLFileConnection connection) {
        this.connection = connection;
    }

    @Override
    public void clearWarnings() {
    }

    @Override
    public void close() {
    }

    /**
     * Execute the interaction spec.
     * The spec define the type of CRUD operation and the file/DOM to perform it on.
     * The spec may also contain and XQuery/XPath to evaluate against the DOM.
     * The input is used for insert/update to contain the data (DOM) to insert into the file.
     */
    @Override
    public Record execute(InteractionSpec spec, Record input) throws ResourceException {
        // Use auto-commit if not in a transaction
        boolean autocommit = false;
        if (!connection.getXMLFileTransaction().isInTransaction()) {
            autocommit = true;
            connection.getXMLFileTransaction().begin();
        }
        try {
            XMLFileInteractionSpec xmlSpec = (XMLFileInteractionSpec)spec;
            File file = new File(this.connection.getConnectionSpec().getDirectory() + "/" + xmlSpec.getFileName());
            Record recordToReturn = null;
            // Check CRUD type and process acordingly
            if (xmlSpec.getInteractionType() == XMLFileInteractionSpec.READ) {
                autocommit = false;
                recordToReturn = executeRead(xmlSpec, file);
            } else if (xmlSpec.getInteractionType() == XMLFileInteractionSpec.INSERT) {
                recordToReturn = executeInsert(xmlSpec, file, (EISDOMRecord)input);
            } else if (xmlSpec.getInteractionType() == XMLFileInteractionSpec.UPDATE) {
                recordToReturn = executeUpdate(xmlSpec, file, (EISDOMRecord)input);
            } else if (xmlSpec.getInteractionType() == XMLFileInteractionSpec.DELETE) {
                recordToReturn = executeDelete(xmlSpec, file);
            }
            if (recordToReturn != null) {
                ((EISDOMRecord) recordToReturn).setSession(((EISDOMRecord)input).getSession());
            }
            return recordToReturn;
        } catch (Exception exception) {
            exception.printStackTrace();
            throw new ResourceException(exception.toString());
        } finally {
            if (autocommit) {
                connection.getXMLFileTransaction().commit();
            }
        }
    }

    /**
     * Execute the read operation.
     */
    public Record executeRead(XMLFileInteractionSpec spec, File file) throws Exception {
        // Parse file and return document, or xpath/xquery result from dom.
        if (!file.exists()) {
            return null;
        }
        EISDOMRecord fileRecord = connection.getXMLFileTransaction().retrieveDOMRecord(file);

        // Check for and process XPath or XQuery
        if (spec.getXPath() != null) {
            // Either a value/string or list of element records is returned
            Object result = fileRecord.getValues(buildField(spec));
            EISDOMRecord output = new EISDOMRecord();
            if (result instanceof List) {
                List<?> results = (List<?>)result;
                output.setDOM(output.createNewDocument("results"));
                for (int index = 0; index < results.size(); index++) {
                    output.add(new DatabaseField("result"), results.get(index));
                }
            } else {
                output.setDOM(output.createNewDocument("results"));
                output.add(new DatabaseField("result"), result);
            }
            return output;
        } else {
            return fileRecord;
        }
    }

    /**
     * Execute the insert operation.
     */
    public Record executeInsert(XMLFileInteractionSpec spec, File file, EISDOMRecord input) throws Exception {
        // Write input record dom to file, or insert dom node.
        EISDOMRecord outputToFile = input;

        // If xpath, parse, insert node, then write back
        if (spec.getXPath() != null) {
            // If the file exists get tx dom.
            outputToFile = connection.getXMLFileTransaction().retrieveDOMRecord(file);
            outputToFile.add(buildField(spec), input);
        }
        return null;
    }

    /**
     * Execute the update operation.
     */
    public Record executeUpdate(XMLFileInteractionSpec spec, File file, EISDOMRecord input) throws Exception {
        // If the file does not exist must first create the file.
        if (!file.exists()) {
            return null;
        }

        // Write input record dom to file, or insert dom node.
        EISDOMRecord outputToFile = input;

        // If xpath, get tx dom, find and update node, (tx commit will write back)
        if (spec.getXPath() != null) {
            outputToFile = connection.getXMLFileTransaction().retrieveDOMRecord(file);
            outputToFile.put(buildField(spec), input);
        }
        return null;
    }

    /**
     * Execute the delete operation.
     */
    public Record executeDelete(XMLFileInteractionSpec spec, File file) throws Exception {
        // Delete file, or remove dom node.
        if (!file.exists()) {
            return null;
        }

        // If xpath, get tx dom, delete node, (tx commit will write back)
        if (spec.getXPath() != null) {
            EISDOMRecord outputToFile = connection.getXMLFileTransaction().retrieveDOMRecord(file);
            outputToFile.remove(buildField(spec));
        } else {
            boolean success = file.delete();

            if (!success) {
                throw EISException.couldNotDeleteFile(new Object[] { file });
            }
        }
        return null;
    }

    /**
     * Execute the interaction and set the output into the output record.
     * Return true or false if the execute returned data (similar to row-count).
     */
    @Override
    public boolean execute(InteractionSpec spec, Record input, Record output) throws ResourceException {
        EISDOMRecord result = (EISDOMRecord)execute(spec, input);
        if (result == null) {
            return false;
        }
        ((EISDOMRecord)output).setDOM(result.getDOM());
        return true;
    }

    @Override
    public Connection getConnection() {
        return connection;
    }

    @Override
    public ResourceWarning getWarnings() {
        return null;
    }

    /**
     * INTERNAL:
     * All values are printed as ? to allow for parameter binding or translation during the execute of the call.
     */
    protected DatabaseField buildField(XMLFileInteractionSpec spec) {
        XMLField xmlField = new XMLField(spec.getXPath());
        xmlField.setNamespaceResolver(spec.getNamespaceResolver());
        return xmlField;
    }
}
