/*
 * 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.oxm.mappings.simpletypes.documentpreservation;


// JDK imports
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;

// XML imports
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

// TopLink imports
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.oxm.XMLUnmarshallerHandler;
import org.eclipse.persistence.oxm.platform.DOMPlatform;
import org.eclipse.persistence.oxm.record.MarshalRecord;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.testing.oxm.OXTestCase;
import org.eclipse.persistence.testing.oxm.mappings.XMLMappingTestCases;
import org.eclipse.persistence.sessions.factories.XMLProjectReader;
import org.eclipse.persistence.sessions.factories.XMLProjectWriter;

public class DocumentPreservationTestCases extends XMLMappingTestCases {
    private final static String XML_RESOURCE = "org/eclipse/persistence/testing/oxm/mappings/simpletypes/documentpreservation/DocumentPreservationTestIn.xml";
    private final static String XML_CONTROL_RESOURCE = "org/eclipse/persistence/testing/oxm/mappings/simpletypes/documentpreservation/DocumentPreservationTestOut.xml";
    private final static String CONTROL_EMPLOYEE_NAME = "Jane Doe";
    private final static String CONTROL_EMPLOYEE_PHONE = "(613)444-1234";
    private XMLContext xmlContext;

    public DocumentPreservationTestCases(String name) throws Exception {
        super(name);
        setControlDocument(XML_CONTROL_RESOURCE);
        setProject(new EmployeeProject());
        //this test is only run with doc pres turned on
        platform = Platform.DOC_PRES;
    }

    @Override
    protected Object getControlObject() {
        Object result;

        try {
            InputStream inputStream = ClassLoader.getSystemResourceAsStream(XML_RESOURCE);
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            builderFactory.setNamespaceAware(true);
            builderFactory.setIgnoringElementContentWhitespace(true);
            DocumentBuilder parser = builderFactory.newDocumentBuilder();
            Document document = parser.parse(inputStream);
            removeEmptyTextNodes(document);

            result = getXMLContext().createUnmarshaller().unmarshal(document);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

        Employee employee = (Employee)result;
        employee.setName(CONTROL_EMPLOYEE_NAME);

        return employee;
    }

    private XMLContext getXMLContext() {
        if (metadata == Metadata.JAVA) {
            if (xmlContext == null) {
                xmlContext = new XMLContext(new EmployeeProject());
                xmlContext.getSession(0).getDatasourceLogin().setPlatform(new DOMPlatform());
            }
            return xmlContext;
        } else {
            if (xmlContext != null) {
                return xmlContext;
            }
            StringWriter stringWriter = new StringWriter();
            XMLProjectWriter writer = new XMLProjectWriter();
            XMLProjectWriter.write(new EmployeeProject(), stringWriter);

            StringReader reader = new StringReader(stringWriter.toString());

            XMLProjectReader projectReader = new XMLProjectReader();
            Project newProject = XMLProjectReader.read(reader);

            XMLContext newContext = new XMLContext(newProject);

            newContext.getSession(0).getDatasourceLogin().setPlatform(new DOMPlatform());
            xmlContext = newContext;
            return newContext;
        }
    }

    @Override
    public void testXMLToObjectFromInputStream() throws Exception {
        InputStream stream = ClassLoader.getSystemResourceAsStream(XML_CONTROL_RESOURCE);
        Object testObject = getXMLContext().createUnmarshaller().unmarshal(stream);
        xmlToObjectTest(testObject);
    }

    /*
        public void testXMLToObjectFromDocument() throws Exception {
            Object testObject = getXMLContext().createUnmarshaller().unmarshal(getControlDocument());
            xmlToObjectTest(testObject);
        }
    */
    @Override
    public void testXMLToObjectFromURL() throws Exception {
        java.net.URL url = ClassLoader.getSystemResource(XML_CONTROL_RESOURCE);
        Object testObject = getXMLContext().createUnmarshaller().unmarshal(url);
        xmlToObjectTest(testObject);
    }

    @Override
    public void testObjectToXMLDocument() throws Exception {
        Document testDocument = getXMLContext().createMarshaller().objectToXML(getWriteControlObject());
        objectToXMLDocumentTest(testDocument);
    }

    @Override
    public void testObjectToXMLStringWriter() throws Exception {
        StringWriter writer = new StringWriter();
        XMLMarshaller marshaller = getXMLContext().createMarshaller();
        marshaller.setFormattedOutput(false);
        marshaller.marshal(getWriteControlObject(), writer);

        StringReader reader = new StringReader(writer.toString());
        InputSource inputSource = new InputSource(reader);
        Document testDocument = parser.parse(inputSource);
        objectToXMLDocumentTest(testDocument);
    }

    @Override
    public void testValidatingMarshal() throws Exception {
        StringWriter writer = new StringWriter();
        XMLMarshaller marshaller = getXMLContext().createMarshaller();
        marshaller.setFormattedOutput(false);
        marshaller.setSchema(FakeSchema.INSTANCE);
        marshaller.marshal(getWriteControlObject(), writer);

        StringReader reader = new StringReader(writer.toString());
        InputSource inputSource = new InputSource(reader);
        Document testDocument = parser.parse(inputSource);
        objectToXMLDocumentTest(testDocument);
    }

    @Override
    public void testObjectToOutputStream() throws Exception {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        XMLMarshaller marshaller = getXMLContext().createMarshaller();
        marshaller.setFormattedOutput(false);
        marshaller.marshal(getWriteControlObject(), stream);

        ByteArrayInputStream is = new ByteArrayInputStream(stream.toByteArray());
        Document testDocument = parser.parse(is);
        objectToXMLDocumentTest(testDocument);
    }
    @Override
    public void testObjectToOutputStreamASCIIEncoding() throws Exception {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        XMLMarshaller marshaller = getXMLContext().createMarshaller();
        marshaller.setFormattedOutput(false);
        marshaller.setEncoding("US-ASCII");
        marshaller.marshal(getWriteControlObject(), stream);

        ByteArrayInputStream is = new ByteArrayInputStream(stream.toByteArray());
        Document testDocument = parser.parse(is);
        objectToXMLDocumentTest(testDocument);
    }

    @Override
    public void testObjectToXMLStreamWriter() throws Exception {
    }

    @Override
    public void testObjectToXMLEventWriter() throws Exception {
    }

    @Override
    public void testUnmarshallerHandler() throws Exception {
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        saxParserFactory.setNamespaceAware(true);
        SAXParser saxParser = saxParserFactory.newSAXParser();
        XMLReader xmlReader = saxParser.getXMLReader();

        XMLUnmarshallerHandler xmlUnmarshallerHandler = getXMLContext().createUnmarshaller().getUnmarshallerHandler();
        xmlReader.setContentHandler(xmlUnmarshallerHandler);

        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XML_CONTROL_RESOURCE);
        InputSource inputSource = new InputSource(inputStream);
        xmlReader.parse(inputSource);

        xmlToObjectTest(xmlUnmarshallerHandler.getResult());
    }

    @Override
    public void testObjectToContentHandler() throws Exception {
        // DO NOTHING BECAUSE CONTENT HANDLER CAN NOT READ COMMENTS
    }

}
