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

import java.io.File;
import java.net.URL;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.PropertyException;
import jakarta.xml.bind.Unmarshaller;
import jakarta.xml.bind.ValidationException;
import jakarta.xml.bind.Validator;
import org.eclipse.persistence.testing.oxm.xmlmarshaller.Car;
import junit.framework.TestCase;

public class ValidatorTestCases extends TestCase {
    private final static String CONTROL_XML_FILE_NAME = "org/eclipse/persistence/testing/oxm/jaxb/Employee_WithAddresses.xml";
    private final static String CONTROL_XML_ADDRESS_FAIL = "org/eclipse/persistence/testing/oxm/jaxb/Employee_WithAddresses_Fail.xml";
    private final static String CONTROL_XML_INHERITANCE_FILE_NAME = "org/eclipse/persistence/testing/oxm/jaxb/Employee_WithPOBoxAddress.xml";
    private final static String CONTROL_JOB_FILE_NAME = "org/eclipse/persistence/testing/oxm/jaxb/Job_Empty.xml";
    private JAXBContext jaxbContext;
    private Validator validator;
    private Unmarshaller unmarshaller;
    private String contextPath;

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

    @Override
    public void setUp() throws Exception {
        contextPath = System.getProperty("jaxb.test.contextpath", JAXBSAXTestSuite.CONTEXT_PATH);

        jaxbContext = JAXBContext.newInstance(contextPath);
        validator = jaxbContext.createValidator();
        unmarshaller = jaxbContext.createUnmarshaller();
    }

    public void testValidateRoot() throws Exception {
        File file = new File(ClassLoader.getSystemResource(CONTROL_XML_FILE_NAME).getFile());
        Object testObject = unmarshaller.unmarshal(file);

        assertTrue("Object did not validate.", validator.validateRoot(testObject));
    }

    public void testValidateElement() throws Exception {
        boolean caughtException = false;
        File file = new File(ClassLoader.getSystemResource(CONTROL_XML_FILE_NAME).getFile());
        Employee employee = (Employee)unmarshaller.unmarshal(file);

        try {
            validator.validate(employee);
        } catch (ValidationException xmlpe) {
            caughtException = true;
        }
        assertFalse("Employee object did not validate.", caughtException);
    }

    public void testValidateComplexType() throws Exception {
        boolean caughtException = false;
        File file = new File(ClassLoader.getSystemResource(CONTROL_XML_FILE_NAME).getFile());
        Employee employee = (Employee)unmarshaller.unmarshal(file);

        try {
            validator.validate(employee.getHomeAddress());
        } catch (ValidationException xmlpe) {
            caughtException = true;
        }
        assertFalse("Address object did not validate.", caughtException);
    }

    public void testValidateInheritanceComplexType() throws Exception {
        boolean caughtException = false;
        File file = new File(ClassLoader.getSystemResource(CONTROL_XML_INHERITANCE_FILE_NAME).getFile());
        Employee employee = (Employee)unmarshaller.unmarshal(file);

        try {
            validator.validate(employee.getHomeAddress());
        } catch (org.eclipse.persistence.platform.xml.XMLPlatformException xmlpe) {
            caughtException = true;
        }
        assertFalse("Address object did not validate.", caughtException);
    }

    public void testValidateSimpleType() throws Exception {
        boolean caughtException = false;
        File file = new File(ClassLoader.getSystemResource(CONTROL_XML_FILE_NAME).getFile());
        Employee employee = (Employee)unmarshaller.unmarshal(file);

        try {
            validator.validate(employee.getPhone());
        } catch (ValidationException xmlpe) {
            caughtException = true;
        }
        assertFalse("Phone object did not validate.", caughtException);
    }

    public void testValidateSimpleTypeID() throws Exception {
        boolean caughtException = false;
        File file = new File(ClassLoader.getSystemResource(CONTROL_XML_FILE_NAME).getFile());
        Employee employee = (Employee)unmarshaller.unmarshal(file);

        try {
            validator.validate(employee.getBadge());
        } catch (ValidationException xmlpe) {
            caughtException = true;
        }
        assertFalse("Badge object did not validate.", caughtException);
    }

    public void testValidateElementException() throws Exception {
        boolean caughtException = false;

        try {
            Employee employee = new Employee();
            validator.validate(employee);
        } catch (ValidationException xmlpe) {
            caughtException = true;
        } catch (Exception ex) {
        }
        assertTrue("JAXBValidator did not throw ValidationException as expected.", caughtException);
    }

    public void testValidateAgainstWrongSchema() throws Exception {
        Job2 job = new Job2();

        try {
            validator.validate(job);
        } catch (ValidationException validationException) {
            assertTrue(true);
            return;
        } catch (Exception ex) {
            fail("An incorrect Exception was thrown");
            return;
        }
        fail("JAXBValidator did not throw ValidationException as expected.");
    }

    public void testValidateNestedComplexType() throws Exception {
        Job job = new Job();

        try {
            validator.validate(job);
        } catch (Exception exception) {
            fail("JAXBValidator threw an unexpected exception." + exception.getMessage());
            return;
        }
    }

    public void testValidateComplexTypeException() throws Exception {
        boolean caughtException = false;

        try {
            Address address = new Address();
            address.setStreet("613 Cedar Lane");
            address.setCity("Bangor");
            address.setState("Maine");
            validator.validate(address);
        } catch (ValidationException xmlpe) {
            caughtException = true;
        } catch (Exception ex) {
        }
        assertTrue("JAXBValidator did not throw ValidationException as expected.", caughtException);
    }

    public void testValidateSimpleTypeException() throws Exception {
        boolean caughtException = false;

        try {
            Phone phone = new Phone();
            phone.setNumber("12345678901");
            validator.validate(phone);
        } catch (ValidationException xmlpe) {
            caughtException = true;
        } catch (Exception ex) {
        }
        assertTrue("JAXBValidator did not throw ValidationException as expected.", caughtException);
    }

    public void testValidateSimpleTypeIDException() throws Exception {
        boolean caughtException = false;

        try {
            Badge badge = new Badge();
            badge.setNumber("11");
            validator.validate(badge);
        } catch (ValidationException xmlpe) {
            caughtException = true;
        } catch (Exception ex) {
        }
        assertTrue("JAXBValidator did not throw ValidationException as expected.", caughtException);
    }

    public void testValidationEventHandler() throws Exception {
        boolean caughtException = false;
        File file = new File(ClassLoader.getSystemResource(CONTROL_XML_ADDRESS_FAIL).getFile());
        Employee employee = (Employee)unmarshaller.unmarshal(file);

        try {
            validator.setEventHandler(new ValidationEventHandlerImpl());
            validator.validate(employee.getHomeAddress());
        } catch (ValidationException xmlpe) {
            caughtException = true;
        } catch (Exception ex) {
        }
        assertFalse("The event handler did not consume the exceptions as expected.", caughtException);
    }

    public void testValidateException() {
        boolean caughtException = false;
        try {
            validator.validate(null);
        } catch (IllegalArgumentException e) {
            caughtException = true;
        } catch (Exception e) {
        }
        assertTrue("JAXBValidator did not throw IllegalArgumentException as expected.", caughtException);
    }

    public void testValidateRootNull() {
        boolean caughtException = false;
        try {
            validator.validateRoot(null);
        } catch (IllegalArgumentException e) {
            caughtException = true;
        } catch (Exception e) {
        }
        assertTrue("JAXBValidator did not throw IllegalArgumentException as expected.", caughtException);
    }

    public void testValidateRootException() {
        boolean caughtException = false;
        try {
            Car car = new Car();
            validator.validateRoot(car);
        } catch (ValidationException e) {
            assertTrue(true);
            return;
        } catch (Exception e) {
            fail("JAXBValidator did not throw ValidationException as expected.");
            return;
        }
        assertTrue("JAXBValidator did not any exceptions, expected a ValidationException.", caughtException);
    }

    public void testSetNullPropertyException() {
        boolean caughtException = false;
        try {
            validator.setProperty(null, null);
        } catch (IllegalArgumentException e) {
            caughtException = true;
        } catch (Exception e) {
        }
        assertTrue("JAXBValidator did not throw IllegalArgumentException as expected.", caughtException);
    }

    public void testGetNullPropertyException() {
        boolean caughtException = false;
        try {
            validator.getProperty(null);
        } catch (IllegalArgumentException e) {
            caughtException = true;
        } catch (Exception e) {
        }
        assertTrue("JAXBValidator did not throw IllegalArgumentException as expected.", caughtException);
    }

    public void testSetInvalidPropertyException() {
        boolean caughtException = false;
        try {
            validator.setProperty("thisIsAnInvalidProperty", "thisIsAnInvalidValue");
        } catch (PropertyException e) {
            caughtException = true;
        } catch (Exception e) {
        }
        assertTrue("JAXBValidator did not throw PropertyException as expected.", caughtException);
    }

    public void testGetInvalidPropertyException() {
        boolean caughtException = false;
        try {
            validator.getProperty("thisIsAnInvalidProperty");
        } catch (PropertyException e) {
            caughtException = true;
        } catch (Exception e) {
        }
        assertTrue("JAXBValidator did not throw PropertyException as expected.", caughtException);
    }

    //=============================== Inner class for eventhandler test =================//
    class ValidationEventHandlerImpl implements jakarta.xml.bind.ValidationEventHandler {
        @Override
        public boolean handleEvent(jakarta.xml.bind.ValidationEvent param1) {
            return true;
        }
    }
}
