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

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

import org.eclipse.persistence.platform.xml.SAXDocumentBuilder;
import org.eclipse.persistence.testing.jaxb.*;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;

import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.Unmarshaller;

public class RootWithCompositeCollectionTestCases extends JAXBWithJSONTestCases {
    public JAXBMarshalListenerImpl listener;
    public JAXBUnmarshalListenerImpl unmarshalListener;
    public ArrayList expectedMarshalEvents;
    public ArrayList expectedUnmarshalEvents;

    public ArrayList expectedClassBasedMarshalEvents;
    public ArrayList expectedClassBasedUnmarshalEvents;

    public Object writeControlObject;

    public RootWithCompositeCollectionTestCases(String name) throws Exception {
        super(name);
        setClasses(new Class[] {Employee.class, Address.class, PhoneNumber.class});
        setControlDocument("org/eclipse/persistence/testing/jaxb/events/composite_collection.xml");
        setControlJSON("org/eclipse/persistence/testing/jaxb/events/composite_collection.json");

        expectedMarshalEvents = new ArrayList();
        expectedMarshalEvents.add(JAXBMarshalListenerImpl.EMPLOYEE_BEFORE_MARSHAL);
        expectedMarshalEvents.add(JAXBMarshalListenerImpl.PHONE_BEFORE_MARSHAL);
        expectedMarshalEvents.add(JAXBMarshalListenerImpl.PHONE_AFTER_MARSHAL);
        expectedMarshalEvents.add(JAXBMarshalListenerImpl.PHONE_BEFORE_MARSHAL);
        expectedMarshalEvents.add(JAXBMarshalListenerImpl.PHONE_AFTER_MARSHAL);
        expectedMarshalEvents.add(JAXBMarshalListenerImpl.EMPLOYEE_AFTER_MARSHAL);

        expectedUnmarshalEvents = new ArrayList();
        expectedUnmarshalEvents.add(JAXBUnmarshalListenerImpl.EMPLOYEE_BEFORE_UNMARSHAL);
        expectedUnmarshalEvents.add(JAXBUnmarshalListenerImpl.PHONE_BEFORE_UNMARSHAL);
        expectedUnmarshalEvents.add(JAXBUnmarshalListenerImpl.PHONE_AFTER_UNMARSHAL);
        expectedUnmarshalEvents.add(JAXBUnmarshalListenerImpl.PHONE_BEFORE_UNMARSHAL);
        expectedUnmarshalEvents.add(JAXBUnmarshalListenerImpl.PHONE_AFTER_UNMARSHAL);
        expectedUnmarshalEvents.add(JAXBUnmarshalListenerImpl.EMPLOYEE_AFTER_UNMARSHAL);

        expectedClassBasedUnmarshalEvents = new ArrayList();
        expectedClassBasedUnmarshalEvents.add(JAXBUnmarshalListenerImpl.EMPLOYEE_BEFORE_UNMARSHAL);
        expectedClassBasedUnmarshalEvents.add(JAXBUnmarshalListenerImpl.EMPLOYEE_AFTER_UNMARSHAL);

        expectedClassBasedMarshalEvents = new ArrayList();
        expectedClassBasedMarshalEvents.add(JAXBMarshalListenerImpl.EMPLOYEE_BEFORE_MARSHAL);
        expectedClassBasedMarshalEvents.add(JAXBMarshalListenerImpl.EMPLOYEE_AFTER_MARSHAL);

    }

    @Override
    public void setUp() throws Exception {
        super.setUp();
        listener = new JAXBMarshalListenerImpl();
        unmarshalListener = new JAXBUnmarshalListenerImpl();

        this.getJAXBMarshaller().setListener(listener);
        this.getJAXBUnmarshaller().setListener(unmarshalListener);
    }
    @Override
    public void xmlToObjectTest(Object testObject) throws Exception {
        super.xmlToObjectTest(testObject);
        assertTrue("Class based callbacks not correct", ((Employee)testObject).triggeredEvents.equals(expectedClassBasedUnmarshalEvents));
        assertTrue("Expected sequence of Unmarshal events not found", expectedUnmarshalEvents.equals(unmarshalListener.events));
        unmarshalListener.events = new ArrayList();

    }

    @Override
    public void jsonToObjectTest(Object testObject) throws Exception {
        super.jsonToObjectTest(testObject);
        assertTrue("Class based callbacks not correct", ((Employee)testObject).triggeredEvents.equals(expectedClassBasedUnmarshalEvents));
        assertTrue("Expected sequence of Unmarshal events not found", expectedUnmarshalEvents.equals(unmarshalListener.events));
        unmarshalListener.events = new ArrayList();

    }

    @Override
    public void objectToXMLDocumentTest(Document testDocument) throws Exception {
        super.objectToXMLDocumentTest(testDocument);
        assertTrue("Class based callbacks not correct", ((Employee)getWriteControlObject()).triggeredEvents.equals(expectedClassBasedMarshalEvents));
        assertTrue("Expected sequence of Marshal events not found", expectedMarshalEvents.equals(listener.events));

    }

    @Override
    public Object getControlObject() {
        Employee employee = new Employee();
        employee.phoneNumbers = new ArrayList();

        PhoneNumber phone = new PhoneNumber();
        phone.number = "123-4567";
        employee.phoneNumbers.add(phone);

        phone = new PhoneNumber();
        phone.number = "891-0111";
        employee.phoneNumbers.add(phone);
        return employee;
    }


    @Override
    public Object getWriteControlObject() {
        if(writeControlObject == null) {
            writeControlObject = getControlObject();
        }
        return writeControlObject;
    }

    @Override
    public void testXMLToObjectFromInputStream() throws Exception {
        InputStream instream = ClassLoader.getSystemResourceAsStream(resourceName);
        Object testObject = getJAXBUnmarshaller().unmarshal(instream);
        instream.close();
        xmlToObjectTest(testObject);
    }

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

    @Override
    public void testObjectToXMLStringWriter() throws Exception {
        StringWriter writer = new StringWriter();
        getJAXBMarshaller().marshal(getWriteControlObject(), writer);

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

        objectToXMLDocumentTest(testDocument);
    }

    @Override
    public void testRoundTrip() throws Exception{
        if(isUnmarshalTest()) {
            InputStream instream = ClassLoader.getSystemResourceAsStream(resourceName);
            Object testObject = getJAXBUnmarshaller().unmarshal(instream);
            instream.close();
            super.xmlToObjectTest(testObject);

            StringWriter writer = new StringWriter();
            getJAXBMarshaller().marshal(testObject, writer);

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

            super.objectToXMLDocumentTest(testDocument);

            assertTrue("Expected sequence of Unmarshal events not found", expectedUnmarshalEvents.equals(unmarshalListener.events));

            assertTrue("Expected sequence of Marshal events not found", expectedMarshalEvents.equals(listener.events));

            ArrayList expectedEvents = new ArrayList();
            expectedEvents.addAll(expectedClassBasedUnmarshalEvents);
            expectedEvents.addAll(expectedClassBasedMarshalEvents);
            assertTrue("Class based callbacks not corrent", ((Employee)testObject).triggeredEvents.equals(expectedEvents));
        }
    }

    @Override
    public void testObjectToContentHandler() throws Exception {
        SAXDocumentBuilder builder = new SAXDocumentBuilder();
        getJAXBMarshaller().marshal(getWriteControlObject(), builder);

        Document controlDocument = getWriteControlDocument();
        Document testDocument = builder.getDocument();

        log("**testObjectToXMLDocument**");
        log("Expected:");
        log(controlDocument);
        log("\nActual:");
        log(testDocument);

        assertXMLIdentical(controlDocument, testDocument);
    }

    @Override
    public void testXMLToObjectFromURL() throws Exception {
        java.net.URL url = ClassLoader.getSystemResource(resourceName);
        Object testObject = getJAXBUnmarshaller().unmarshal(url);
        xmlToObjectTest(testObject);
    }

    @Override
    public void testUnmarshallerHandler() throws Exception {
    }
}
