/*
 * Copyright (c) eHealth
 */
package be.ehealth.business.mycarenetcommons.builders.impl;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

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

import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import be.ehealth.business.mycarenetcommons.domain.CareProvider;
import be.ehealth.business.mycarenetcommons.domain.Identification;
import be.ehealth.business.mycarenetcommons.domain.Nihii;
import be.ehealth.technicalconnector.config.ConfigFactory;
import be.ehealth.technicalconnector.config.ConfigValidator;
import be.ehealth.technicalconnector.exception.TechnicalConnectorException;


/**
 * Test of the generic common builder
 * 
 * @author EHP
 */
public class GenericCommonBuilderImplTest extends AbstractCommonBuilderImplTest {

    private static final Logger LOG = LoggerFactory.getLogger(GenericCommonBuilderImplTest.class);

    private static final String MYCARENET_DEFAULT_CAREPROVIDER_NIHII_VALUE = "mycarenet.default.careprovider.nihii.value";

    private static final String MYCARENET_DEFAULT_CAREPROVIDER_NIHII_QUALITY = "mycarenet.default.careprovider.nihii.quality";

    private static GenericCommonBuilderImpl builder = new GenericCommonBuilderImpl();

    private static ConfigValidator config = ConfigFactory.getConfigValidator();


    @BeforeClass
    public static void init() throws Exception {
        config = ConfigFactory.getConfigValidator();

        initGenericCommonBuilderImpl();
    }

    @Test
    public void testCreateCareProviderForOrigin() throws Exception {
        String nihiiQuality = "PHARMACY-HOLDER";
        String nihiiValue = "21247651001";
        String personName = "A Pharmacy Holder";
        String personSsin = "79011735327";
        String organizationName = "A Pharmacy";
        String organisationNihiiQuality = "PHARMACY";
        String organizationNihiiValue = "66666714";

        Nihii nihii = new Nihii(nihiiQuality, nihiiValue);
        Identification person = new Identification();
        person.setName(personName);
        person.setSsin(personSsin);
        Identification organization = new Identification();
        organization.setName(organizationName);
        organization.setNihii(new Nihii(organisationNihiiQuality, organizationNihiiValue));

        setCareProviderProperties(nihii, organization, person);

        CareProvider careProvider = builder.createCareProviderForOrigin();

        logCareProvider(careProvider);

        assertCareProviderEquals(nihii, person, organization, careProvider);

    }

    /**
     * @param nihii
     * @param person
     * @param organization
     * @param careProvider
     */
    private void assertCareProviderEquals(Nihii expectedNihii, Identification expectedPerson, Identification expectedOrganization, CareProvider actualCareProvider) {
        assertNotNull(actualCareProvider);
        assertNihiiEquals(expectedNihii, actualCareProvider.getNihii());

        Identification actualOrganisation = actualCareProvider.getOrganization();
        assertNotNull(actualOrganisation);
        assertNihiiEquals(expectedOrganization.getNihii(), actualOrganisation.getNihii());
        assertEquals(expectedOrganization.getCbe(), actualOrganisation.getCbe());
        assertEquals(expectedOrganization.getName(), actualOrganisation.getName());
        assertEquals(expectedOrganization.getSsin(), actualOrganisation.getSsin());

        Identification actualPerson = actualCareProvider.getPhysicalPerson();
        assertNotNull(actualPerson);
        assertEquals(expectedPerson.getName(), actualPerson.getName());
        assertEquals(expectedPerson.getSsin(), actualPerson.getSsin());
        assertEquals(expectedPerson.getCbe(), actualPerson.getCbe());
        assertNihiiEquals(expectedPerson.getNihii(), actualPerson.getNihii());
    }

    /**
     * @param nihii
     * @param careProvider
     */
    private void assertNihiiEquals(Nihii expectedNihii, Nihii actualNihii) {
        if (expectedNihii != null) {
            assertNotNull(actualNihii);
            assertNotNull(actualNihii.getQuality());
            assertNotNull(actualNihii.getValue());
            assertEquals(expectedNihii.getQuality(), actualNihii.getQuality());
            assertEquals(expectedNihii.getValue(), actualNihii.getValue());
        } else {
            assertNull(actualNihii);
        }
    }

    /**
     * @param nihii
     * @param organization
     * @param person
     */
    private void setCareProviderProperties(Nihii nihii, Identification organization, Identification person) throws TechnicalConnectorException {
        config.setProperty(MYCARENET_DEFAULT_CAREPROVIDER_NIHII_QUALITY, nihii.getQuality());
        config.setProperty(MYCARENET_DEFAULT_CAREPROVIDER_NIHII_VALUE, nihii.getValue());
        config.setProperty("mycarenet.default.careprovider.physicalperson.name", person.getName());
        Nihii nihii2 = person.getNihii();
        if (nihii2 != null) {
            config.setProperty("mycarenet.default.careprovider.physicalperson.nihii.quality", nihii2.getQuality());
            config.setProperty("mycarenet.default.careprovider.physicalperson.nihii.value", nihii2.getValue());
        }
        config.setProperty("mycarenet.default.careprovider.physicalperson.ssin", person.getSsin());
        config.setProperty("mycarenet.default.careprovider.organization.name", organization.getName());
        config.setProperty("mycarenet.default.careprovider.organization.nihii.quality", organization.getNihii().getQuality());
        config.setProperty("mycarenet.default.careprovider.organization.nihii.value", organization.getNihii().getValue());
        config.setProperty("mycarenet.default.careprovider.organization.cbe", organization.getCbe());
    }

    /**
     * @param careProvider
     */
    private void logCareProvider(CareProvider careProvider) {
        StringBuilder sb = new StringBuilder();
        sb.append("CareProvider :::\n");
        sb.append("nihii : " + careProvider.getNihii().getValue() + " " + careProvider.getNihii().getQuality() + "\n");
        Identification organization = careProvider.getOrganization();
        if (organization != null) {
            sb.append("Organization:\n \tcbe: " + organization.getCbe() + "\n");
            sb.append("\tnihii: " + organization.getNihii() + "\n");
            sb.append("\tname: " + organization.getName() + "\n");
        }
        Identification physicalPerson = careProvider.getPhysicalPerson();
        if (physicalPerson != null) {
            sb.append("Person:\n\tname:" + physicalPerson.getName() + "\n");
            sb.append("\tSsin: " + physicalPerson.getSsin() + "\n");
            sb.append("\tNihii: " + physicalPerson.getNihii() + "\n");
        }
        LOG.info(sb.toString());
    }

    private static void initGenericCommonBuilderImpl() throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("projectName", "default");
        builder.initialize(map);
    }

}
