/*
 * Copyright (c) 2015, 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:
//     Dmitry Kornilov - initial implementation
package org.eclipse.persistence.testing.osgi.beanvalidation;

import org.eclipse.persistence.exceptions.BeanValidationException;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.MarshallerProperties;
import org.eclipse.persistence.testing.osgi.OSGITestHelper;
import org.hibernate.validator.HibernateValidator;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerClass;

import jakarta.validation.Validation;
import jakarta.validation.ValidationProviderResolver;
import jakarta.validation.ValidatorFactory;
import jakarta.validation.spi.ValidationProvider;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.Unmarshaller;

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

import static org.junit.Assert.assertTrue;

/**
 * Marshal/unmarshal + validation tests in OSGi container with installed bean validation implementation bundles.
 * The purpose of these tests is to make sure that bean validation works in OSGi environment.
 *
 * @author Dmitry Kornilov
 * @since 2.7.0
 */
@RunWith(PaxExam.class)
@ExamReactorStrategy(PerClass.class)
public class BeanValidationTest extends BaseBeanValidationTest {
    private static JAXBContext jaxbContext;

    @Configuration
    public static Option[] config() {
        return OSGITestHelper.getOptionsWithBeanValidation();
    }

    @BeforeClass
    public static void setUp() throws Exception {
        Class<?>[] classes = new Class<?>[1];
        classes[0] = Customer.class;
        jaxbContext = JAXBContextFactory.createContext(classes, null);
    }

    @Test(expected = BeanValidationException.class)
    public void testMarshalInvalid() throws JAXBException {
        StringWriter xml = new StringWriter();
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty(MarshallerProperties.BEAN_VALIDATION_FACTORY, getValidatorFactory());
        marshaller.marshal(createInvalidCustomer(), xml);
    }

    @Test
    public void testMarshalValid() throws JAXBException {
        StringWriter xml = new StringWriter();
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty(MarshallerProperties.BEAN_VALIDATION_FACTORY, getValidatorFactory());
        marshaller.marshal(createValidCustomer(), xml);
        assertTrue(xml.toString().contains(CUSTOMER_VALID_XML));
    }

    @Test(expected = JAXBException.class)
    public void testUnmarshalInvalid() throws JAXBException {
        StringReader xml = new StringReader(CUSTOMER_INVALID_XML);
        Unmarshaller unmarshaler = jaxbContext.createUnmarshaller();
        unmarshaler.setProperty(MarshallerProperties.BEAN_VALIDATION_FACTORY, getValidatorFactory());
        unmarshaler.unmarshal(xml);
    }

    @Test
    public void testUnmarshalValid() throws JAXBException {
        StringReader xml = new StringReader(CUSTOMER_VALID_XML);
        Unmarshaller unmarshaler = jaxbContext.createUnmarshaller();
        unmarshaler.setProperty(MarshallerProperties.BEAN_VALIDATION_FACTORY, getValidatorFactory());
        Customer testCustomer = (Customer)unmarshaler.unmarshal(xml);
        assertTrue(createValidCustomer().equals(testCustomer));
    }

    private ValidatorFactory getValidatorFactory() {
        return Validation.byProvider(HibernateValidator.class)
                .providerResolver(new BeanValidationTest.MyValidationProviderResolver())
                .configure()
                .buildValidatorFactory();
    }

    private static class MyValidationProviderResolver implements ValidationProviderResolver {
        @Override
        public List<ValidationProvider<?>> getValidationProviders() {
            return Collections.<ValidationProvider<?>>singletonList(new HibernateValidator());
        }
    }
}