/*
 * Copyright (c) 2011, 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:
//  - rbarkhouse - 23 April 2012 - 2.4 - Initial implementation
package org.eclipse.persistence.testing.jaxb.cycle;

import java.io.ByteArrayOutputStream;

import jakarta.xml.bind.Marshaller;

import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.testing.jaxb.JAXBWithJSONTestCases;

public class CycleRecoverableTestCases extends JAXBWithJSONTestCases {

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

    public CycleRecoverableTestCases(String name) throws Exception {
        super(name);

        setControlDocument(XML_RESOURCE);
        setControlJSON(JSON_RESOURCE);
        setClasses(new Class[] { Company.class, EmployeePointer.class });
    }

    @Override
    public boolean isUnmarshalTest() {
        return false;
    }

    public void testEqualsUsingEqualsMethod() throws Exception {
        Marshaller m = getJAXBMarshaller();

        // Use equals() method for object comparison.
        // Email's equals() always returns false, so Cycle cannot be detected.
        // Expecting StackOverflowError.
        m.setProperty("org.glassfish.jaxb.objectIdentitityCycleDetection", false);

        Email em1 = new Email(); em1.user = "me"; em1.domain = "here.com";
        Email em2 = new Email(); em2.user = "myself"; em2.domain = "overthere.co.uk";
        em1.forward = em2; em2.forward = em1;

        Throwable expectedException = null;
        try {
            m.marshal(em1, new ByteArrayOutputStream());
        } catch (Throwable ex) {
            expectedException = ex;
        }

        assertNotNull("No exception caught as expected.", expectedException);
        assertEquals("Incorrect exception caught.", StackOverflowError.class, expectedException.getClass());

        m.setProperty("org.glassfish.jaxb.objectIdentitityCycleDetection", true);
    }

    public void testUnhandledCycle() throws Exception {
        Company c = (Company) getControlObject();

        Employee e = new Employee();
        e.id = 40;
        e.name = "Fred Flintstone";
        ContactInfo info = new ContactInfo();
        Email em = new Email();
        em.user = "bcfred";
        em.domain = "slate.com";
        info.email = em;

        // Introduce unhandled cycle
        em.parentInfo = info;

        e.contactInfos.add(info);
        c.employees.add(e);

        // jakarta.xml.bind.MarshalException
        //      -> XMLMarshalException: An error occurred marshalling the object
        //              -> XMLMarshalException: A cycle is detected in the object graph.
        XMLMarshalException expectedException = null;
        try {
            Marshaller m = getJAXBContext().createMarshaller();
            //m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            //m.setProperty(JAXBMarshaller.MEDIA_TYPE, "application/json");
            //m.marshal(c, System.out);
            m.marshal(c, new ByteArrayOutputStream());
        } catch (Exception ex) {
            expectedException = (XMLMarshalException) ex.getCause();
        }

        assertNotNull("No exception caught as expected.", expectedException);
        XMLMarshalException xmlMarshalException = (XMLMarshalException) expectedException;
        assertEquals("Incorrect exception code.", xmlMarshalException.getErrorCode(), XMLMarshalException.OBJECT_CYCLE_DETECTED);
    }

    @Override
    protected Object getControlObject() {
        Company c = new Company();
        c.name = "ACME Incorporated";

        Employee e1 = new Employee();
        e1.id = 789;
        e1.name = "Bob Smith";

        Employee e2 = new Employee();
        e2.id = 1234;
        e2.name = "Jane Doe";

        ContactInfo info1 = new ContactInfo();
        Address a1 = new Address();
        a1.addressString = "123 Main St.";
        info1.address = a1;
        PhoneNumber p1 = new PhoneNumber();
        p1.number = 5551212;
        info1.phoneNumber = p1;
        e1.contactInfos.add(info1);

        ContactInfo info2 = new ContactInfo();
        Address a2 = new Address();
        a2.addressString = "727 Water St.";
        info2.address = a2;
        PhoneNumber p2 = new PhoneNumber();
        p2.number = 5551655;
        info2.phoneNumber = p2;
        e1.contactInfos.add(info2);

        ContactInfo info3 = new ContactInfo();
        Address a3 = new Address();
        a3.addressString = "711 Maple Ave.";
        info3.address = a3;
        PhoneNumber p3 = new PhoneNumber();
        p3.number = 5559876;
        info3.phoneNumber = p3;
        Email em3 = new Email();
        em3.user = "Jane.Doe";
        em3.domain = "oracle.com";
        info3.email = em3;
        e2.contactInfos.add(info3);

        // Introduce object-cycles, which will be handled by
        // Employee.onCycleDetected
        p2.owningEmployee = e1;
        p3.owningEmployee = e2;

        c.employees.add(e1);
        c.employees.add(e2);

        return c;
    }

}
