/*
 * Copyright (c) Smals
 */
package be.ehealth.technicalconnector.config;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.ehealth.technicalconnector.utils.ConfigurableFactoryHelper;


/**
 * tests the workings of the configFactory.
 * 
 * @author EHP
 * 
 * 
 * 
 */
@SuppressWarnings("deprecation")
public class ConfigurableFactoryHelperTest {

    @Before
    public void resetTest() {
        ConfigFactory.invalidate();

    }

    @Test(expected = TechnicalConnectorException.class)
    public void testWithoutDefaultClass() throws TechnicalConnectorException {
        ConfigFactoryTest cftest;
        ConfigurableFactoryHelper<ConfigFactoryTest> helperFactoryresponseBuilder = new ConfigurableFactoryHelper<ConfigFactoryTest>(null, null, ConfigFactoryTest.class);
        cftest = helperFactoryresponseBuilder.getImplementation(new HashMap<String, Object>(), false);
        Assert.assertNull(cftest);
    }

    @Test(expected = TechnicalConnectorException.class)
    public void testGetImplementationMissingConfigMap() throws TechnicalConnectorException {
        ConfigurableFactoryHelper<SomeBusinessInterface> factoryHelper = new ConfigurableFactoryHelper<SomeBusinessInterface>("nonExistingPropertyName", "be.ehealth.technicalconnector.config.ConfigurableImplementationImpl", SomeBusinessInterface.class);
        factoryHelper.getImplementation(null, false);
    }

    @Test
    public void testGetImplementationsMissingConfigMap() throws TechnicalConnectorException {
        ConfigurableFactoryHelper<SomeBusinessInterface> factoryHelper = new ConfigurableFactoryHelper<SomeBusinessInterface>("nonExistingPropertyName", "be.ehealth.technicalconnector.config.ConfigurableImplementationImpl", SomeBusinessInterface.class);
        List<SomeBusinessInterface> implementations = factoryHelper.getImplementations();
        Assert.assertTrue(implementations.isEmpty());
        // the loading of the implementation failed with error ( which is logged, but not rethrown )
    }

    @Test
    public void testGetImplementationWithConfigMap() throws TechnicalConnectorException {
        Map<String, Object> configMap = new HashMap<String, Object>();
        configMap.put("some.config.property", "configObject");
        ConfigurableFactoryHelper<SomeBusinessInterface> factoryHelper = new ConfigurableFactoryHelper<SomeBusinessInterface>("nonExistingPropertyName", "be.ehealth.technicalconnector.config.ConfigurableImplementationImpl", SomeBusinessInterface.class);
        SomeBusinessInterface someBusinessInterface = factoryHelper.getImplementation(configMap);
        Assert.assertEquals(1, someBusinessInterface.getParameterMap()
                                                    .keySet()
                                                    .size());
        Assert.assertTrue(someBusinessInterface.getParameterMap()
                                               .keySet()
                                               .contains("some.config.property"));
        Assert.assertEquals("configObject", someBusinessInterface.getParameterMap()
                                                                 .get("some.config.property"));
    }

    @Test
    public void testGetImplementationsWithConfigMap() throws TechnicalConnectorException {
        Map<String, Object> configMap = new HashMap<String, Object>();
        configMap.put("some.config.property", "configObject");
        ConfigurableFactoryHelper<SomeBusinessInterface> factoryHelper = new ConfigurableFactoryHelper<SomeBusinessInterface>("nonExistingPropertyName", "be.ehealth.technicalconnector.config.ConfigurableImplementationImpl", SomeBusinessInterface.class);
        List<SomeBusinessInterface> implementations = factoryHelper.getImplementations(configMap);
        Assert.assertNotNull(implementations);
        Assert.assertEquals(1, implementations.size());
        SomeBusinessInterface someBusinessInterface = implementations.get(0);
        Assert.assertEquals(1, someBusinessInterface.getParameterMap()
                                                    .keySet()
                                                    .size());
        Assert.assertTrue(someBusinessInterface.getParameterMap()
                                               .keySet()
                                               .contains("some.config.property"));
        Assert.assertEquals("configObject", someBusinessInterface.getParameterMap()
                                                                 .get("some.config.property"));
    }

    @Test(expected = TechnicalConnectorException.class)
    public void testGetImplementationMissingConfigMapWithCache() throws TechnicalConnectorException {
        ConfigurableFactoryHelper<SomeBusinessInterface> factoryHelper = new ConfigurableFactoryHelper<SomeBusinessInterface>("nonExistingPropertyName", "be.ehealth.technicalconnector.config.ConfigurableImplementationImpl", SomeBusinessInterface.class);
        factoryHelper.getImplementation(true);
    }

    @Test
    public void testGetImplementationsMissingConfigMapWithCache() throws TechnicalConnectorException {
        ConfigurableFactoryHelper<SomeBusinessInterface> factoryHelper = new ConfigurableFactoryHelper<SomeBusinessInterface>("nonExistingPropertyName", "be.ehealth.technicalconnector.config.ConfigurableImplementationImpl", SomeBusinessInterface.class);
        List<SomeBusinessInterface> implementations = factoryHelper.getImplementations(true);
        for (SomeBusinessInterface implementation : implementations) {
            System.out.println(implementation.getClass());
        }

        Assert.assertTrue(implementations.isEmpty());
        // the loading of the implementation failed with error ( missing config properties ) ( which is logged, but not rethrown )

    }

    @Test
    public void testGetImplementationWithConfigMapWithCache() throws TechnicalConnectorException {
        Map<String, Object> configMap = new HashMap<String, Object>();
        configMap.put("some.config.property", "configObject");
        ConfigurableFactoryHelper<SomeBusinessInterface> factoryHelper = new ConfigurableFactoryHelper<SomeBusinessInterface>("nonExistingPropertyName", "be.ehealth.technicalconnector.config.ConfigurableImplementationImpl", SomeBusinessInterface.class);
        SomeBusinessInterface someBusinessInterface = factoryHelper.getImplementation(configMap);
        Assert.assertEquals(1, someBusinessInterface.getParameterMap()
                                                    .keySet()
                                                    .size());
        Assert.assertTrue(someBusinessInterface.getParameterMap()
                                               .keySet()
                                               .contains("some.config.property"));
        Assert.assertEquals("configObject", someBusinessInterface.getParameterMap()
                                                                 .get("some.config.property"));

    }

    @Test
    public void testGetImplementationsWithConfigMapWithCache() throws TechnicalConnectorException {
        Map<String, Object> configMap = new HashMap<String, Object>();
        configMap.put("some.config.property", "configObject");
        ConfigurableFactoryHelper<SomeBusinessInterface> factoryHelper = new ConfigurableFactoryHelper<SomeBusinessInterface>("nonExistingPropertyName", "be.ehealth.technicalconnector.config.ConfigurableImplementationImpl", SomeBusinessInterface.class);
        List<SomeBusinessInterface> implementations = factoryHelper.getImplementations(configMap, true);
        Assert.assertNotNull(implementations);
        Assert.assertEquals(1, implementations.size());
        SomeBusinessInterface someBusinessInterface = implementations.get(0);
        Assert.assertEquals(1, someBusinessInterface.getParameterMap()
                                                    .keySet()
                                                    .size());
        Assert.assertTrue(someBusinessInterface.getParameterMap()
                                               .keySet()
                                               .contains("some.config.property"));
        Assert.assertEquals("configObject", someBusinessInterface.getParameterMap()
                                                                 .get("some.config.property"));
    }


}
