/*
 * Copyright (c) 2013, 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:
//     Blaise Doughan - 2.4.2 - initial implementation
package org.eclipse.persistence.testing.jaxb.xmlmarshaller;

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

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.UnmarshalException;
import jakarta.xml.bind.Unmarshaller;
import jakarta.xml.bind.ValidationEvent;
import jakarta.xml.bind.ValidationEventHandler;
import jakarta.xml.bind.annotation.XmlRootElement;

import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.xml.sax.Locator;
import org.xml.sax.SAXParseException;

import junit.framework.TestCase;

public class HandleListenerExceptionsTestCases extends TestCase {

    private static String AFTER_MARSHAL = "afterMarshal";
    private static String AFTER_UNMARSHAL = "afterUnmarshal";
    private static String BEFORE_MARSHAL = "beforeMarshal";
    private static String BEFORE_UNMARSHAL = "beforeUnmarshal";
    private static String XML = "<foo><bar/></foo>";

    private JAXBContext jc;

    @Override
    protected void setUp() throws Exception {
        jc = JAXBContextFactory.createContext(new Class[] {Foo.class}, null);
        //jc = JAXBContext.newInstance(Foo.class);
    }

    public void testUnmarshal() throws Exception {
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        TestValidationEventHandler veh = new TestValidationEventHandler();
        unmarshaller.setEventHandler(veh);

        StringReader reader = new StringReader(XML);
        unmarshaller.unmarshal(reader);

        assertEquals(2, veh.validationEvents.size());

        ValidationEvent veh1 = veh.validationEvents.get(0);
        assertEquals(ValidationEvent.FATAL_ERROR, veh1.getSeverity());
        assertTrue(veh1.getLinkedException() instanceof XMLMarshalException);
        assertEquals(BEFORE_UNMARSHAL, veh1.getLinkedException().getCause().getCause().getMessage());

        ValidationEvent veh2 = veh.validationEvents.get(1);
        assertEquals(ValidationEvent.FATAL_ERROR, veh2.getSeverity());
        assertTrue(veh2.getLinkedException() instanceof XMLMarshalException);
        assertEquals(AFTER_UNMARSHAL, veh2.getLinkedException().getCause().getCause().getMessage());
    }

    public void testMarshal() throws Exception {
        Marshaller marshaller = jc.createMarshaller();
        TestValidationEventHandler veh = new TestValidationEventHandler();
        marshaller.setEventHandler(veh);

        Foo foo = new Foo();
        foo.bar = new Bar();

        marshaller.marshal(foo, new StringWriter());

        assertEquals(2, veh.validationEvents.size());

        ValidationEvent veh1 = veh.validationEvents.get(0);
        assertEquals(ValidationEvent.FATAL_ERROR, veh1.getSeverity());
        assertTrue(veh1.getLinkedException() instanceof XMLMarshalException);
        assertEquals(BEFORE_MARSHAL, veh1.getLinkedException().getCause().getCause().getMessage());

        ValidationEvent veh2 = veh.validationEvents.get(1);
        assertEquals(ValidationEvent.FATAL_ERROR, veh2.getSeverity());
        assertTrue(veh2.getLinkedException() instanceof XMLMarshalException);
        assertEquals(AFTER_MARSHAL, veh2.getLinkedException().getCause().getCause().getMessage());

    }

    @XmlRootElement
    public static class Foo {

        public Bar bar;

    }

    public static class Bar {

        private void afterMarshal(Marshaller marshaller) {
            throw new RuntimeException(AFTER_MARSHAL);
        }

        private void afterUnmarshal(Unmarshaller unmarshaller, Object object) {
            throw new RuntimeException(AFTER_UNMARSHAL);
        }

        private void beforeMarshal(Marshaller marshaller) {
            throw new RuntimeException(BEFORE_MARSHAL);
        }

        private void beforeUnmarshal(Unmarshaller unmarshaller, Object object) {
            throw new RuntimeException(BEFORE_UNMARSHAL);
        }

    }

    public static class TestValidationEventHandler implements ValidationEventHandler {

        List<ValidationEvent> validationEvents = new ArrayList<ValidationEvent>(2);

        public List<ValidationEvent> getValidationEvents() {
            return validationEvents;
        }

        @Override
        public boolean handleEvent(ValidationEvent validationEvent) {
            this.validationEvents.add(validationEvent);
            return true;
        }

    }

}
