/*
 * Copyright (c) 1998, 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:
// dmccann - April 7/2009 - 2.0 - Initial implementation
package org.eclipse.persistence.testing.jaxb.events.sessionevents;

import java.util.Iterator;

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;

import org.eclipse.persistence.core.sessions.CoreProject;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.jaxb.JaxbClassLoader;
import org.eclipse.persistence.internal.jaxb.SessionEventListener;
import org.eclipse.persistence.jaxb.compiler.Generator;
import org.eclipse.persistence.jaxb.javamodel.reflection.JavaModelImpl;
import org.eclipse.persistence.jaxb.javamodel.reflection.JavaModelInputImpl;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.sessions.Project;

import junit.framework.TestCase;

/**
 * Tests use of custom Session event handling, such as disabling InstantiationPolicy
 * validation during Descriptor initialization.
 */
public class SessionEventTestCases extends TestCase {

    public SessionEventTestCases(String name) throws Exception {
        super(name);
    }

    /**
     * InstantiationPolicy validation should fail due to recursive constructor calls.
     * Test expects an exception.
     */
    public void testInstantiationPolicyValidationFailure() {
        Class[] classesToBeBound = new Class[] { Subclass.class, Superclass.class };

        // ensure instantiation policy validation is enabled during descriptor initialization
        SessionEventListener eventListener = new SessionEventListener();
        eventListener.setShouldValidateInstantiationPolicy(true);

        try {
            setupContext(classesToBeBound, eventListener);
        } catch (Exception x) {
            return;
        }
        fail("An exception did not occur as expected");
    }

    /**
     * Tests disabling of InstantiationPolicy validation during descriptor
     * initialization. Test should pass w/o any exceptions.
     */
    public void testInstantiationPolicyValidationDisabled() {
        Class[] classesToBeBound = new Class[] { Subclass.class, Superclass.class };

        // disable instantiation policy validation during descriptor initialization
        SessionEventListener eventListener = new SessionEventListener();
        eventListener.setShouldValidateInstantiationPolicy(false);

        try {
            setupContext(classesToBeBound, eventListener);
        } catch (Exception x) {
            fail("An unexpected exception occurred: [" + x.getMessage() + "]");
        }
    }

    protected JAXBContext setupContext(Class[] classesToBeBound, SessionEventListener sel) throws Exception {
        jakarta.xml.bind.JAXBContext jaxbContext = null;
        XMLContext xmlContext = null;
        JaxbClassLoader loader = new JaxbClassLoader(Thread.currentThread().getContextClassLoader());
        try {
            Generator generator = new Generator(new JavaModelInputImpl(classesToBeBound, new JavaModelImpl(loader)));

            CoreProject proj = generator.generateProject();

            ConversionManager conversionManager = null;
            conversionManager = new ConversionManager();
            conversionManager.setLoader(loader);

            proj.convertClassNamesToClasses(conversionManager.getLoader());
            for (Iterator<ClassDescriptor> descriptorIt = proj.getOrderedDescriptors().iterator(); descriptorIt.hasNext();) {
                ClassDescriptor descriptor = descriptorIt.next();
                if (descriptor.getJavaClass() == null) {
                    descriptor.setJavaClass(conversionManager.convertClassNameToClass(descriptor.getJavaClassName()));
                }
            }

            xmlContext = new XMLContext((Project)proj, loader, sel);
            jaxbContext = new org.eclipse.persistence.jaxb.JAXBContext(xmlContext, generator, classesToBeBound);
        } catch (Exception ex) {
            throw ex;
        }
        return jaxbContext;
    }
}
