/*
 * 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.testing.sdo.helper.xmlhelper.loadandsave;

import commonj.sdo.Type;
import commonj.sdo.helper.XMLDocument;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.eclipse.persistence.testing.sdo.helper.xmlhelper.SDOXMLHelperTestCases;
import org.eclipse.persistence.sdo.SDOConstants;
import org.eclipse.persistence.sdo.SDOType;
import org.eclipse.persistence.sdo.helper.SDOXMLHelper;
import org.eclipse.persistence.sdo.helper.extension.SDOUtil;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;

public abstract class LoadAndSaveWithOptionsTestCases extends SDOXMLHelperTestCases {
    public LoadAndSaveWithOptionsTestCases(String name) {
        super(name);
    }

    protected String getNoSchemaControlFileName() {
        return getControlFileName();
    }

    protected String getNoSchemaControlWriteFileName() {
        return getNoSchemaControlFileName();
    }

    protected String getControlDataObjectFileName() {
        return getControlWriteFileName();
    }

    protected String getUnrelatedSchemaName() {
        return "./org/eclipse/persistence/testing/sdo/helper/xmlhelper/PurchaseOrder.xsd";
    }

    abstract protected String getSchemaName();

    abstract protected String getControlFileName();

    abstract protected void registerTypes();


    abstract protected String getControlRootName();

    protected String getControlWriteFileName() {
        return getControlFileName();
    }

    protected String getControlRootURI() {
        return NON_DEFAULT_URI;
    }

    public String getFullClassPackageName(Type aType) {
        StringBuffer className = new StringBuffer(SDOUtil.getPackageNameFromURI(aType.getURI()));
        className.append(SDOConstants.JAVA_PACKAGE_NAME_SEPARATOR);
        className.append(aType.getName().substring(0,1).toUpperCase());
        className.append(aType.getName().substring(1));
        return className.toString();
    }

    public void verifyPackageNameGeneratedFromURI(String uri, String typeName) {
        Type aType = typeHelper.getType(uri, typeName);
        String className = ((SDOType)aType).getInstanceClassName();
        String mangledClassName = getFullClassPackageName(aType);
        assertEquals(mangledClassName, className);
    }

    // Override package generation based on the JAXB 2.0 algorithm in SDOUtil.java
    protected List<String> getPackages() {
        List<String> packages = new ArrayList<String>();
        packages.add(NON_DEFAULT_JAVA_PACKAGE_DIR);
        return packages;
    }

    public void testLoadFromInputStreamSaveDocumentToOutputStream() throws Exception {
        defineTypes();

        FileInputStream inputStream = new FileInputStream(getControlFileName());
        XMLDocument document = xmlHelper.load(inputStream, null, getOptions());
        verifyAfterLoad(document);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        xmlHelper.save(document, outputStream, null);

        compareXML(getControlWriteFileName(), outputStream.toString());

    }

    //
    public void testNoSchemaLoadFromInputStreamSaveDataObjectToString() throws Exception {
        registerTypes();
        FileInputStream inputStream = new FileInputStream(getNoSchemaControlFileName());
        XMLDocument document = xmlHelper.load(inputStream, null, getOptions());
        verifyAfterLoad(document);
        StringWriter writer = new StringWriter();
        xmlHelper.save(document, writer, null);
        // Nodes will not be the same but XML output is
        compareXML(getNoSchemaControlWriteFileName(), writer.toString());//, false);
    }

    //
    public void testLoadFromInputStreamWithURIAndOptionsSaveDataObjectToOutputStream() throws Exception {
        defineTypes();
        FileInputStream inputStream = new FileInputStream(getControlFileName());
        XMLDocument document = xmlHelper.load(inputStream, null, getOptions());// xsi:type will be written out
        verifyAfterLoad(document);

        ByteArrayOutputStream outstream = new ByteArrayOutputStream();
        xmlHelper.save(document.getRootObject(), getControlRootURI(), getControlRootName(), outstream);
        compareXML(getControlDataObjectFileName(), outstream.toString());

    }

    //
    // xpaths/doms null
    public void testLoadFromFileReaderWithURIAndOptionsStreamSaveDataObjectToWriter() throws Exception {
        defineTypes();
        FileReader reader = new FileReader(getControlFileName());
        XMLDocument document = xmlHelper.load(reader, null, getOptions());
        verifyAfterLoad(document);

        String s = xmlHelper.save(document.getRootObject(), getControlRootURI(), getControlRootName());
        compareXML(getControlDataObjectFileName(), s);
    }

    // okay except will set isDirty=true which will clear marshalledObject in xmlMarshaller
    public void testLoadFromAndSaveAfterDefineMultipleSchemas() throws Exception {
        defineTypes();
        xsdHelper.define(getSchema(getUnrelatedSchemaName()));
        FileInputStream inputStream = new FileInputStream(getControlFileName());
        XMLDocument document = xmlHelper.load(inputStream, null, getOptions());// xsi:type will be written out
        verifyAfterLoad(document);
        String s = xmlHelper.save(document.getRootObject(), getControlRootURI(), getControlRootName());
        compareXML(getControlDataObjectFileName(), s);

    }

    public void testLoadFromInputStreamWithURIAndOptionsSaveDataObjectToStreamResult() throws Exception {
        DocumentBuilderFactory factory;
        DocumentBuilder builder;
        Document document1 = null;

        //DOMSource source = null;
        defineTypes();
        factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        factory.setValidating(false);
        builder = factory.newDocumentBuilder();

        document1 = builder.parse(new File(getControlFileName()));
        document1.toString();
        //source = new DOMSource(document1);
        XMLDocument document = xmlHelper.load(new FileInputStream(getControlFileName()), null, getOptions());
        verifyAfterLoad(document);

        ByteArrayOutputStream outstream = new ByteArrayOutputStream();

        StreamResult result = new StreamResult(outstream);
        xmlHelper.save(document, result, null);
        compareXML(getControlWriteFileName(), result.getOutputStream().toString());

    }

    public void testLoadFromDomSourceWithURIAndOptionsSaveDataObjectToStreamResult() throws Exception {
        DocumentBuilderFactory factory;
        DocumentBuilder builder;
        Document document1 = null;
        DOMSource source = null;

        defineTypes();

        factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        factory.setValidating(false);
        builder = factory.newDocumentBuilder();

        document1 = builder.parse(new File(getControlFileName()));

        source = new DOMSource(document1);

        XMLDocument document = xmlHelper.load(source, null, getOptions());
        verifyAfterLoad(document);

        ByteArrayOutputStream outstream = new ByteArrayOutputStream();

        StreamResult result = new StreamResult(outstream);

        xmlHelper.save(document, result, null);
        compareXML(getControlWriteFileName(), result.getOutputStream().toString());

    }

    public void testLoadFromSAXSourceWithURIAndOptionsSaveDataObjectToStreamResult() throws Exception {
        SAXSource source = null;

        defineTypes();
        FileInputStream inputStream = new FileInputStream(getControlFileName());
        source = new SAXSource(new InputSource(inputStream));

        XMLDocument document = xmlHelper.load(source, null, getOptions());
        verifyAfterLoad(document);

        ByteArrayOutputStream outstream = new ByteArrayOutputStream();
        StreamResult result = new StreamResult(outstream);

        xmlHelper.save(document, result, null);
        compareXML(getControlWriteFileName(), result.getOutputStream().toString());

    }

    public void testLoadFromStreamSourceWithURIAndOptionsSaveDataObjectToStreamResult() throws Exception {
        StreamSource source = null;

        defineTypes();

        FileInputStream inputStream = new FileInputStream(getControlFileName());

        source = new StreamSource(inputStream);

        XMLDocument document = xmlHelper.load(source, null, getOptions());
        verifyAfterLoad(document);

        ByteArrayOutputStream outstream = new ByteArrayOutputStream();

        StreamResult result = new StreamResult(outstream);

        xmlHelper.save(document, result, null);
        compareXML(getControlWriteFileName(), result.getOutputStream().toString());

    }

    protected void compareXML(String controlFileName, String testString) throws Exception {
        compareXML(controlFileName, testString, true);
    }

    protected void compareXML(String controlFileName, String testString, boolean compareNodes) throws Exception {
        String controlString = removeCopyrightFromString(getControlString(controlFileName));
        log("Expected:" + controlString);
        log("Actual  :" + testString);

        StringReader reader = new StringReader(testString);
        InputSource inputSource = new InputSource(reader);
        Document testDocument = parser.parse(inputSource);
        reader.close();

        if (compareNodes) {
            Document controlDocument = getDocument(controlFileName);
            removeCopyrightNode(controlDocument);
            assertXMLIdentical(controlDocument, testDocument);
        }
    }

    protected String getControlString(String fileName) {
        try {
            FileInputStream inputStream = new FileInputStream(fileName);
            byte[] bytes = new byte[inputStream.available()];
            inputStream.read(bytes);
            return new String(bytes);
        } catch (Exception e) {
            e.printStackTrace();
            fail("An error occurred loading the control document");
            return null;
        }
    }

    protected void verifyAfterLoad(XMLDocument document) {
        assertNotNull(document);
        assertNotNull(document.getRootObject());
        assertNull(document.getRootObject().getContainer());
    }

    protected List defineTypes() {
        return xsdHelper.define(getSchema(getSchemaName()));
    }

    protected String getSchemaLocation() {
        return "";
    }

    protected Object getOptions() {
        return null;
    }
}
