/*
 * 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.testing.jaxb.xmlmarshaller;

import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.MarshalException;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.Unmarshaller;
import jakarta.xml.bind.util.JAXBResult;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.dom.DOMResult;

import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.platform.xml.SAXDocumentBuilder;
import org.eclipse.persistence.testing.oxm.OXTestCase;
import org.eclipse.persistence.testing.oxm.xmlmarshaller.Car;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;

public class MarshallerTestCases extends OXTestCase {
    private final static String CONTROL_XML_FILE_NAME = "org/eclipse/persistence/testing/oxm/jaxb/Employee.xml";
    private final static String CONTROL_EMPLOYEE_NAME = "Jane Doe";
    private JAXBContext jaxbContext;
    private Marshaller marshaller;
    private DocumentBuilder parser;
    private String contextPath;

    public MarshallerTestCases(String name) {
        super(name);
    }

    public void setUp() throws Exception {
        contextPath = System.getProperty("jaxb.test.contextpath", JAXBSAXTestSuite.CONTEXT_PATH);

        jaxbContext = JAXBContext.newInstance(contextPath, getClass().getClassLoader());
        marshaller = jaxbContext.createMarshaller();
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        builderFactory.setIgnoringElementContentWhitespace(true);
        parser = builderFactory.newDocumentBuilder();
    }

    /**
     * Since JAXB delegates all of its functionality to XMLMarshaller, there is
     * no need to re-test all of the various marshal/unmarshal methods.
     */
    public void testMarshalObjectToWriter() throws Exception {
        StringWriter writer = new StringWriter();
        marshaller.marshal(getControlObject(), writer);

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

        assertXMLIdentical(getControlDocument(), testDocument);
    }

    public void testMarshalObjectToJAXBResult() throws Exception {
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        JAXBResult jaxbResult = new JAXBResult(unmarshaller);

        marshaller.marshal(getControlObject(), jaxbResult);
    }

    public void testMarshalToWriterException() {
        boolean caughtException = false;
        try {
            marshaller.marshal(null, (Writer)null);
        } catch (IllegalArgumentException e) {
            caughtException = true;
        } catch (Exception e) {
        }
        assertTrue("JAXBMarshaller did not throw IllegalArgumentException as expected.", caughtException);
    }

    public void testMarshalToContentHandlerException() {
        boolean caughtException = false;
        try {
            marshaller.marshal(null, (ContentHandler)null);
        } catch (IllegalArgumentException e) {
            caughtException = true;
        } catch (Exception e) {
        }
        assertTrue("JAXBMarshaller did not throw IllegalArgumentException as expected.", caughtException);
    }

    public void testMarshalObjectToContentHandler() throws Exception {
        SAXDocumentBuilder builder = new SAXDocumentBuilder();

        marshaller.marshal(getControlObject(), builder);

        log(getControlDocument());
        log(builder.getDocument());

        assertXMLIdentical(getControlDocument(), builder.getDocument());
    }

    public void testMarshalToNodeException() {
        boolean caughtException = false;
        try {
            marshaller.marshal(null, (Node)null);
        } catch (IllegalArgumentException e) {
            caughtException = true;
        } catch (Exception e) {
        }
        assertTrue("JAXBMarshaller did not throw IllegalArgumentException as expected.", caughtException);
    }

    public void testMarshalToNullOutputStream() {
        boolean caughtException = false;
        try {
            marshaller.marshal(null, (OutputStream)null);
        } catch (IllegalArgumentException e) {
            caughtException = true;
        } catch (Exception e) {
        }
        assertTrue("JAXBMarshaller did not throw IllegalArgumentException as expected.", caughtException);
    }

    public void testMarshalToInvalidOutputStream() {
        try {
            FileDescriptor fd = new FileDescriptor();
            FileOutputStream filestream = new FileOutputStream(fd);

            marshaller.marshal(getControlObject(), filestream);
        } catch (MarshalException e) {
            assertTrue(true);
            return;
        } catch (Exception e) {
            e.printStackTrace();
            fail("An unexpected exeption was thrown.");
            return;
        }
        fail("JAXBMarshaller did not throw an exception as expected.");
    }

    /**
     * We should throw an exception if users try to marshal an object which is
     * not of a type that is mapped in the project. The class Car is not mapped
     * in the project being used so an exception should be thrown
     */
    public void testMarshalInvalidObject() {
        StringWriter writer = new StringWriter();

        try {
            marshaller.marshal(new Car(), writer);
        } catch (MarshalException jaxbex) {
            Throwable internalException = jaxbex.getLinkedException();
            assertTrue("LinkedException was not an XMLMarshalException as expected. ", internalException instanceof XMLMarshalException);
            assertTrue("LinkedException did not contain error code [25007 - DESCRIPTOR_NOT_FOUND_IN_PROJECT] as expected. ", ((XMLMarshalException)internalException).getErrorCode() == XMLMarshalException.DESCRIPTOR_NOT_FOUND_IN_PROJECT);
            return;
        } catch (Exception e) {
            log(e.getMessage());
            assertTrue("An XMLMarshalException should have been caught but wasn't.", false);
        }
        assertTrue("An XMLMarshalException should have been caught but wasn't.", false);
    }

    public void testMarshalToResultException() {
        boolean caughtException = false;
        try {
            marshaller.marshal(null, (Result)null);
        } catch (IllegalArgumentException e) {
            caughtException = true;
        } catch (Exception e) {
        }
        assertTrue("JAXBMarshaller did not throw IllegalArgumentException as expected.", caughtException);
    }

    // =============================================================
    public void testMarshalToInvalidResult() throws Exception {
        boolean caughtException = false;
        Document document = parser.newDocument();
        DOMResult result = new DOMResult(document.createAttribute("test"));

        try {
            marshaller.marshal(getControlObject(), result);
        } catch (IllegalArgumentException e) {
            caughtException = false;
        } catch (MarshalException e) {
            caughtException = true;
        }
        assertTrue("JAXBMarshaller did not throw JAXBException as expected.", caughtException);
    }

    public void testMarshalToInvalidNode() throws Exception {
        boolean caughtException = false;
        Document document = parser.newDocument();

        try {
            marshaller.marshal(getControlObject(), document.createAttribute("test"));
        } catch (IllegalArgumentException e) {
            caughtException = false;
        } catch (MarshalException e) {
            caughtException = true;
        }
        assertTrue("JAXBMarshaller did not throw JAXBException as expected.", caughtException);
    }

    // =============================================================
    private Object getControlObject() {
        Employee employee = new Employee();
        employee.setName(CONTROL_EMPLOYEE_NAME);
        return employee;
    }

    private Document getControlDocument() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(CONTROL_XML_FILE_NAME);
        Document document = parser.parse(inputStream);
        removeEmptyTextNodes(document);
        return document;
    }
}
