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

import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.util.ArrayList;

import junit.framework.TestCase;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLLogin;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.oxm.platform.SAXPlatform;
import org.eclipse.persistence.oxm.platform.XMLPlatform;

import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.testing.oxm.OXTestCase;
import org.w3c.dom.Document;

public class TwoProjectsTestSuite extends OXTestCase {
    private static final String CONTEXT_PATH_DOM = "TwoProjects-Customer-DOM:TwoProjects-Employee-DOM";
    private static final String CONTEXT_PATH_SAX = "TwoProjects-Customer-SAX:TwoProjects-Employee-SAX";
    private static final String XML_RESOURCE_CUSTOMER = "org/eclipse/persistence/testing/oxm/xmlmarshaller/twoprojects/customer.xml";
    private static final String XML_RESOURCE_EMPLOYEE = "org/eclipse/persistence/testing/oxm/xmlmarshaller/twoprojects/employee.xml";
    private static final String CONTROL_ADDRESS_STREET = "123 A Street";
    private static final String CONTROL_ADDRESS_CITY = "Any Town";
    private static final String CONTROL_PHONE_NUMBER_VALUE = "613-555-1111";
    private DocumentBuilder parser;
    private XMLMarshaller xmlMarshaller;
    private XMLUnmarshaller xmlUnmarshaller;

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

    public static void main(String[] args) {
        junit.textui.TestRunner.main(new String[] { "-c", "org.eclipse.persistence.testing.oxm.xmlmarshaller.twoprojects.TwoProjectsTestSuite" });
    }

    @Override
    public void setUp() throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        parser = dbf.newDocumentBuilder();
    }

    public void testAddLoggedInSession() throws Exception {
        XMLContext xmlContext = new XMLContext(new CustomerProject());
        Project empProject = new EmployeeProject();
        XMLPlatform platform = new SAXPlatform();
        empProject.setLogin(new XMLLogin(platform));

        DatabaseSession employeeSession = empProject.createDatabaseSession();

        employeeSession.login();
        xmlContext.addSession(employeeSession);

        xmlMarshaller = xmlContext.createMarshaller();
        Employee employee = getControlEmployee();
        Document controlDocument = getControlDocument(XML_RESOURCE_EMPLOYEE);

        Document testDocument = parser.newDocument();
        xmlMarshaller.marshal(employee, testDocument);
        log("\nExpected:");
        log(controlDocument);
        log("\nActual:");
        log(testDocument);
        log("");

        this.assertXMLIdentical(controlDocument, testDocument);
    }

    public void testAddLoggedOutSession() throws Exception {
        XMLContext xmlContext = new XMLContext(new CustomerProject());
        Project empProject = new EmployeeProject();

        XMLPlatform platform = new SAXPlatform();
        empProject.setLogin(new XMLLogin(platform));

        DatabaseSession employeeSession = empProject.createDatabaseSession();
        employeeSession.logout();
        xmlContext.addSession(employeeSession);

        xmlMarshaller = xmlContext.createMarshaller();
        Employee employee = getControlEmployee();
        Document controlDocument = getControlDocument(XML_RESOURCE_EMPLOYEE);

        Document testDocument = parser.newDocument();
        xmlMarshaller.marshal(employee, testDocument);
        log("\nExpected:");
        log(controlDocument);
        log("\nActual:");
        log(testDocument);
        log("");

        this.assertXMLIdentical(controlDocument, testDocument);
    }

    public void testAddDuplicateSession() throws Exception {
        XMLContext xmlContext = new XMLContext(CONTEXT_PATH_SAX);

        Project empProject = new EmployeeProject();
        XMLPlatform platform = new SAXPlatform();
        empProject.setLogin(new XMLLogin(platform));

        DatabaseSession employeeSession = empProject.createDatabaseSession();

        xmlContext.addSession(employeeSession);

        xmlMarshaller = xmlContext.createMarshaller();
        Employee employee = getControlEmployee();
        Document controlDocument = getControlDocument(XML_RESOURCE_EMPLOYEE);

        Document testDocument = parser.newDocument();
        xmlMarshaller.marshal(employee, testDocument);
        log("\nExpected:");
        log(controlDocument);
        log("\nActual:");
        log(testDocument);
        log("");

        this.assertXMLIdentical(controlDocument, testDocument);

        int numSessions = xmlContext.getSessions().size();
        assertEquals(3, numSessions);
    }

    public void testMarshalCustomerSAX() throws Exception {
        XMLContext xmlContext = new XMLContext(CONTEXT_PATH_SAX);
        xmlMarshaller = xmlContext.createMarshaller();

        Customer customer = getControlCustomer();
        Document controlDocument = getControlDocument(XML_RESOURCE_CUSTOMER);

        Document testDocument = parser.newDocument();
        xmlMarshaller.marshal(customer, testDocument);
        log("\nExpected:");
        log(controlDocument);
        log("\nActual:");
        log(testDocument);
        log("");

        this.assertXMLIdentical(controlDocument, testDocument);
    }

    public void testMarshalCustomerCollectionConstructor() throws Exception {
        ArrayList projects = new ArrayList();
        projects.add(new CustomerProject());
        projects.add(new EmployeeProject());
        XMLContext xmlContext = new XMLContext(projects);
        xmlMarshaller = xmlContext.createMarshaller();

        Customer customer = getControlCustomer();
        Document controlDocument = getControlDocument(XML_RESOURCE_CUSTOMER);

        Document testDocument = parser.newDocument();
        xmlMarshaller.marshal(customer, testDocument);
        log("\nExpected:");
        log(controlDocument);
        log("\nActual:");
        log(testDocument);
        log("");

        this.assertXMLIdentical(controlDocument, testDocument);
    }

    public void testUnmarshalCustomerSAX() throws Exception {
        XMLContext xmlContext = new XMLContext(CONTEXT_PATH_SAX);
        xmlUnmarshaller = xmlContext.createUnmarshaller();

        Customer controlCustomer = getControlCustomer();
        InputStream instream = ClassLoader.getSystemResourceAsStream(XML_RESOURCE_CUSTOMER);
        Customer testCustomer = (Customer)xmlUnmarshaller.unmarshal(instream);

        log("\nExpected:");
        log(controlCustomer.toString());
        log("\nActual:");
        log(testCustomer.toString());
        log("");

        assertEquals(controlCustomer, testCustomer);
    }

    public void testUnmarshalCustomerCollectionConstructor() throws Exception {
        ArrayList projects = new ArrayList();
        projects.add(new CustomerProject());
        projects.add(new EmployeeProject());
        XMLContext xmlContext = new XMLContext(projects);
        xmlUnmarshaller = xmlContext.createUnmarshaller();

        Customer controlCustomer = getControlCustomer();
        InputStream instream = ClassLoader.getSystemResourceAsStream(XML_RESOURCE_CUSTOMER);
        Customer testCustomer = (Customer)xmlUnmarshaller.unmarshal(instream);

        log("\nExpected:");
        log(controlCustomer.toString());
        log("\nActual:");
        log(testCustomer.toString());
        log("");

        assertEquals(controlCustomer, testCustomer);
    }

    public void testMarshalEmployeeSAX() throws Exception {
        XMLContext xmlContext = new XMLContext(CONTEXT_PATH_SAX);
        xmlMarshaller = xmlContext.createMarshaller();

        Employee employee = getControlEmployee();
        Document controlDocument = getControlDocument(XML_RESOURCE_EMPLOYEE);

        Document testDocument = parser.newDocument();
        xmlMarshaller.marshal(employee, testDocument);
        log("\nExpected:");
        log(controlDocument);
        log("\nActual:");
        log(testDocument);
        log("");

        this.assertXMLIdentical(controlDocument, testDocument);
    }

    public void testMarshalEmployeeCollectionConstructor() throws Exception {
        ArrayList projects = new ArrayList();
        projects.add(new CustomerProject());
        projects.add(new EmployeeProject());
        XMLContext xmlContext = new XMLContext(projects);
        xmlMarshaller = xmlContext.createMarshaller();

        Employee employee = getControlEmployee();
        Document controlDocument = getControlDocument(XML_RESOURCE_EMPLOYEE);

        Document testDocument = parser.newDocument();
        xmlMarshaller.marshal(employee, testDocument);
        log("\nExpected:");
        log(controlDocument);
        log("\nActual:");
        log(testDocument);
        log("");

        this.assertXMLIdentical(controlDocument, testDocument);
    }

    public void testUnmarshalEmployeeSAX() throws Exception {
        XMLContext xmlContext = new XMLContext(CONTEXT_PATH_SAX);
        xmlUnmarshaller = xmlContext.createUnmarshaller();

        Employee controlEmployee = getControlEmployee();
        InputStream instream = ClassLoader.getSystemResourceAsStream(XML_RESOURCE_EMPLOYEE);
        Employee testEmployee = (Employee)xmlUnmarshaller.unmarshal(instream);

        log("\nExpected:");
        log(controlEmployee.toString());
        log("\nActual:");
        log(testEmployee.toString());
        log("");

        assertEquals(controlEmployee, testEmployee);
    }

    public void testUnmarshalEmployeeCollectionConstructor() throws Exception {
        ArrayList projects = new ArrayList();
        projects.add(new CustomerProject());
        projects.add(new EmployeeProject());
        XMLContext xmlContext = new XMLContext(projects);

        xmlUnmarshaller = xmlContext.createUnmarshaller();

        Employee controlEmployee = getControlEmployee();
        InputStream instream = ClassLoader.getSystemResourceAsStream(XML_RESOURCE_EMPLOYEE);
        Employee testEmployee = (Employee)xmlUnmarshaller.unmarshal(instream);

        log("\nExpected:");
        log(controlEmployee.toString());
        log("\nActual:");
        log(testEmployee.toString());
        log("");

        assertEquals(controlEmployee, testEmployee);
    }

    public void testMarshalCustomerDOM() throws Exception {
        XMLContext xmlContext = new XMLContext(CONTEXT_PATH_DOM);
        xmlMarshaller = xmlContext.createMarshaller();

        Customer customer = getControlCustomer();
        Document controlDocument = getControlDocument(XML_RESOURCE_CUSTOMER);

        Document testDocument = parser.newDocument();
        xmlMarshaller.marshal(customer, testDocument);
        log("\nExpected:");
        log(controlDocument);
        log("\nActual:");
        log(testDocument);
        log("");

        this.assertXMLIdentical(controlDocument, testDocument);
    }

    public void testUnmarshalCustomerDOM() throws Exception {
        XMLContext xmlContext = new XMLContext(CONTEXT_PATH_DOM);
        xmlUnmarshaller = xmlContext.createUnmarshaller();

        Customer controlCustomer = getControlCustomer();
        InputStream instream = ClassLoader.getSystemResourceAsStream(XML_RESOURCE_CUSTOMER);
        Customer testCustomer = (Customer)xmlUnmarshaller.unmarshal(instream);

        log("\nExpected:");
        log(controlCustomer.toString());
        log("\nActual:");
        log(testCustomer.toString());
        log("");

        assertEquals(controlCustomer, testCustomer);
    }

    public void testMarshalEmployeeDOM() throws Exception {
        XMLContext xmlContext = new XMLContext(CONTEXT_PATH_DOM);
        xmlMarshaller = xmlContext.createMarshaller();

        Employee employee = getControlEmployee();
        Document controlDocument = getControlDocument(XML_RESOURCE_EMPLOYEE);

        Document testDocument = parser.newDocument();
        xmlMarshaller.marshal(employee, testDocument);
        log("\nExpected:");
        log(controlDocument);
        log("\nActual:");
        log(testDocument);
        log("");

        this.assertXMLIdentical(controlDocument, testDocument);
    }

    public void testUnmarshalEmployeeDOM() throws Exception {
        XMLContext xmlContext = new XMLContext(CONTEXT_PATH_DOM);
        xmlUnmarshaller = xmlContext.createUnmarshaller();

        Employee controlEmployee = getControlEmployee();
        InputStream instream = ClassLoader.getSystemResourceAsStream(XML_RESOURCE_EMPLOYEE);
        Employee testEmployee = (Employee)xmlUnmarshaller.unmarshal(instream);

        log("\nExpected:");
        log(controlEmployee.toString());
        log("\nActual:");
        log(testEmployee.toString());
        log("");

        assertEquals(controlEmployee, testEmployee);
    }

    private Document getControlDocument(String resourceName) throws Exception {
        InputStream instream = ClassLoader.getSystemResourceAsStream(resourceName);
        return parser.parse(instream);
    }

    private Customer getControlCustomer() {
        Customer customer = new Customer();
        Address address = new Address();
        address.setStreet(CONTROL_ADDRESS_STREET);
        address.setCity(CONTROL_ADDRESS_CITY);
        customer.setAddress(address);
        customer.getAddresses().add(address);
        PhoneNumber phoneNumber = new PhoneNumber();
        phoneNumber.setValue(CONTROL_PHONE_NUMBER_VALUE);
        customer.setAny(phoneNumber);
        customer.getAnyCollection().add(phoneNumber);
        return customer;
    }

    private Employee getControlEmployee() {
        Employee employee = new Employee();
        Address address = new Address();
        address.setStreet(CONTROL_ADDRESS_STREET);
        address.setCity(CONTROL_ADDRESS_CITY);
        employee.setAddress(address);
        employee.getAddresses().add(address);
        return employee;
    }
}
