/*
 * Copyright (c) 2014, 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:
//     Marcel Valovy - 2.6.0 - initial implementation
package org.eclipse.persistence.testing.jaxb.casesensitivity;

import java.net.URL;
import java.util.HashMap;
import java.util.Map;

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

import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.eclipse.persistence.jaxb.UnmarshallerProperties;
import org.eclipse.persistence.testing.jaxb.casesensitivity.correctCase.CustomerImpl;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * Tests the functionality correctness of the case insensitive unmarshalling feature.
 *
 * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=331241">EclipseLink Forum, Bug 331241.</a>
 * @author Marcel Valovy - marcel.valovy@oracle.com
 */
public class JAXBCaseInsensitivityTestCase extends junit.framework.TestCase {

    private static final URL CUSTOMER_FILE_URL = Thread.currentThread().getContextClassLoader().getResource("org/eclipse/persistence/testing/jaxb/casesensitivity/customer.xml");
    @SuppressWarnings({"unchecked"})
    private static final Class<Customer>[] CAMEL_CASE_CUSTOMER = (Class<Customer>[]) new Class[]{CustomerImpl.class};
    @SuppressWarnings({"unchecked"})
    private static final Class<Customer>[] UPPER_CASE_CUSTOMER = (Class<Customer>[]) new Class[]{org.eclipse.persistence.testing.jaxb.casesensitivity.otherCase.CustomerImpl.class};
    private static final boolean DEBUG = false;

    private CustomerImpl baseCustomer;
    private Unmarshaller unmarshallerCorrectCaseInsensitive;
    private Unmarshaller unmarshallerOtherCaseInsensitive;
    private Unmarshaller unmarshallerCorrectCaseSensitive;
    private Unmarshaller unmarshallerOtherCaseSensitive;

    @Test
    public void testMain() throws Exception {

        if (DEBUG) System.out.println("Case-insensitive unmarshalling test.");
            assertTrue(unmarshalOtherCaseInsensitive().equals(baseCustomer));
            CustomerImpl ciCorrect = unmarshalCorrectCaseInsensitive();
            assertTrue(ciCorrect.equals(baseCustomer));
            assertTrue(null == ciCorrect.getPersonalName());
                if (DEBUG) System.out.println("Collision handled correctly.");


        if (DEBUG) System.out.println("Case-sensitive unmarshalling test.");
            assertFalse(unmarshalOtherCaseSensitive().equals(baseCustomer));
            assertTrue(unmarshalCorrectCaseSensitive().equals(baseCustomer));
    }

    /* Case-insensitive part */
    private CustomerImpl unmarshalCorrectCaseInsensitive() throws JAXBException {

        CustomerImpl correctCaseCustomer = (CustomerImpl) unmarshallerCorrectCaseInsensitive.unmarshal(CUSTOMER_FILE_URL);
        if (DEBUG) System.out.println(correctCaseCustomer);

        return correctCaseCustomer;
    }

    private org.eclipse.persistence.testing.jaxb.casesensitivity.otherCase.CustomerImpl unmarshalOtherCaseInsensitive() throws JAXBException {

        org.eclipse.persistence.testing.jaxb.casesensitivity.otherCase.CustomerImpl otherCaseCustomer
                = (org.eclipse.persistence.testing.jaxb.casesensitivity.otherCase.CustomerImpl) unmarshallerOtherCaseInsensitive.unmarshal(CUSTOMER_FILE_URL);
        if (DEBUG) System.out.println(otherCaseCustomer);

        return otherCaseCustomer;
    }

    /* Case-sensitive part */
    private CustomerImpl unmarshalCorrectCaseSensitive() throws JAXBException {

        CustomerImpl correctCaseCustomer = (CustomerImpl) unmarshallerCorrectCaseSensitive.unmarshal(CUSTOMER_FILE_URL);
        if (DEBUG) System.out.println(correctCaseCustomer);

        return correctCaseCustomer;
    }

    private org.eclipse.persistence.testing.jaxb.casesensitivity.otherCase.CustomerImpl unmarshalOtherCaseSensitive() throws JAXBException {

        org.eclipse.persistence.testing.jaxb.casesensitivity.otherCase.CustomerImpl otherCaseCustomer
                = (org.eclipse.persistence.testing.jaxb.casesensitivity.otherCase.CustomerImpl) unmarshallerOtherCaseSensitive.unmarshal(CUSTOMER_FILE_URL);
        if (DEBUG) System.out.println(otherCaseCustomer);

        return otherCaseCustomer;
    }

    @Override
    @Before
    public void setUp() throws Exception {
        baseCustomer = new CustomerImpl();
        baseCustomer.setId(1234007);
        baseCustomer.setAge(24);
        baseCustomer.setPersonalname("collisionBabe");
        baseCustomer.setPersonalName("cafeBabe");

        /* Create and assign case-insensitive unmarshallers */
        Map<String, Object> properties = new HashMap<>();
        properties.put(JAXBContextProperties.UNMARSHALLING_CASE_INSENSITIVE, Boolean.TRUE);
        JAXBContext ctxCorrectCaseInsensitive = JAXBContextFactory.createContext(CAMEL_CASE_CUSTOMER, properties);
        JAXBContext ctxOtherCaseInsensitive = JAXBContextFactory.createContext(UPPER_CASE_CUSTOMER, null); /* we set CI by setProperty() */

        unmarshallerCorrectCaseInsensitive = ctxCorrectCaseInsensitive.createUnmarshaller();
        unmarshallerOtherCaseInsensitive = ctxOtherCaseInsensitive.createUnmarshaller();
        unmarshallerOtherCaseInsensitive.setProperty(UnmarshallerProperties.UNMARSHALLING_CASE_INSENSITIVE, Boolean.TRUE);

        /* Create and assign case-sensitive unmarshallers */
        properties.put(JAXBContextProperties.UNMARSHALLING_CASE_INSENSITIVE, Boolean.FALSE);
        JAXBContext ctxCorrectCaseSensitive = JAXBContextFactory.createContext(CAMEL_CASE_CUSTOMER, properties);

        /* Test that the property can be turned off by using case insensitive context and altering its property */
        unmarshallerOtherCaseSensitive = ctxOtherCaseInsensitive.createUnmarshaller();
        unmarshallerOtherCaseSensitive.setProperty(UnmarshallerProperties.UNMARSHALLING_CASE_INSENSITIVE, Boolean.FALSE);
        unmarshallerCorrectCaseSensitive = ctxCorrectCaseSensitive.createUnmarshaller();
    }

    @Override
    @After
    public void tearDown() throws Exception {
        baseCustomer = null;
        unmarshallerCorrectCaseInsensitive = unmarshallerOtherCaseInsensitive = unmarshallerCorrectCaseSensitive = unmarshallerOtherCaseSensitive = null;
    }
}
