/*
 * 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:
// dmccann - August 6/2009 - 2.0 - Initial implementation
package org.eclipse.persistence.testing.jaxb.externalizedmetadata.xmlcustomizer;

import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.persistence.jaxb.JAXBContext;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.testing.jaxb.JAXBWithJSONTestCases;
import org.eclipse.persistence.testing.oxm.OXTestCase;

/**
 * Tests XmlCustomizer - this annotation facilitates descriptor customization.
 *
 */
public class XmlCustomizerTestCases extends JAXBWithJSONTestCases {

    private static final String XML_RESOURCE = "org/eclipse/persistence/testing/jaxb/externalizedmetadata/xmlcustomizer/employee_no_overrides.xml";
    private static final String JSON_RESOURCE = "org/eclipse/persistence/testing/jaxb/externalizedmetadata/xmlcustomizer/employee_no_overrides.json";

    /**
     * Test @XmlCustomizer annotation on the Java class.  Here, no XML override
     * is performed.  The instance doc will contain 'first-name' and 'last-name'
     * tags which were changed by the customizer from 'firstName' and
     * 'lastName' respectively.
     *
     * Positive test.
     */
    public XmlCustomizerTestCases(String name) throws Exception {
        super(name);
        setClasses(new Class[]{Employee.class});
        setControlDocument(XML_RESOURCE);
        setControlJSON(JSON_RESOURCE);
    }

    public void testSchemaGen() throws Exception{
        List controlSchemas = new ArrayList();
        InputStream is = ClassLoader.getSystemResourceAsStream("org/eclipse/persistence/testing/jaxb/externalizedmetadata/xmlcustomizer/employee.xsd");

        controlSchemas.add(is);

        super.testSchemaGen(controlSchemas);


    }

    /**
     * Test @XmlCustomizer annotation on the Java class.  Here, no XML override
     * is performed.  The instance doc will contain 'firstName' and 'lastName'
     * tags which will have been changed by the customizer to 'first-name' and
     * 'last-name' respectively.
     *
     * Negative test.
     * @throws JAXBException
     */
    public void testXmlCustomizerNoOverrideFail() throws JAXBException {
        Class<?>[] classes = {
                Employee.class
            };

        JAXBContext jaxbContext = null;
        try {
            jaxbContext = (JAXBContext) JAXBContextFactory.createContext(classes, null);
        } catch (JAXBException e) {
            e.printStackTrace();
            fail("An unexpected exception occurred");
        }

        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        Marshaller marshaller = jaxbContext.createMarshaller();

        Object obj;
        try {
            // test unmarshal
            obj = unmarshaller.unmarshal(new StreamSource(new StringReader(getInstanceDocumentInvalid())));
            assertFalse("Unmarshal operation succeeded unexpectedly", obj.equals(getControlObject()));

            // test marshal
            StringWriter sw = new StringWriter();
            marshaller.marshal(getControlObject(), sw);

            String ctrlString = OXTestCase.removeWhiteSpaceFromString(getInstanceDocumentInvalid());
            String testString = OXTestCase.removeWhiteSpaceFromString(sw.toString());
            assertFalse("Comparison succeeded unexpectedly", ctrlString.equals(testString));
        } catch (JAXBException e) {
            fail("An unexpected exception occurred");
        }
    }

    private String getInstanceDocumentInvalid() {
        return "<?xml version=\"1.0\" encoding=\"UTF-8\"?><employee><firstName>Joe</firstName><lastName>Oracle</lastName></employee>";
    }

    @Override
    public Object getControlObject() {
        Employee emp = new Employee();
        emp.firstName = "Joe";
        emp.lastName = "Oracle";
        return emp;
    }
}
