/*
 * Copyright (c) Smals
 */
package be.ehealth.business.mycarenetcommons.validator;

import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.unitils.UnitilsJUnit4TestClassRunner;
import org.unitils.reflectionassert.ReflectionAssert;

import be.ehealth.business.mycarenetcommons.domain.CareProvider;
import be.ehealth.business.mycarenetcommons.domain.CommonInput;
import be.ehealth.business.mycarenetcommons.domain.Identification;
import be.ehealth.business.mycarenetcommons.domain.Nihii;
import be.ehealth.business.mycarenetcommons.domain.Origin;
import be.ehealth.business.mycarenetcommons.domain.Party;
import be.ehealth.business.mycarenetcommons.exception.ConnectorValidationException;
import be.ehealth.business.mycarenetcommons.exception.ValidationError;
import be.ehealth.technicalconnector.config.util.domain.PackageInfo;


/**
 * tests the CommonInputValidator.
 * 
 * @author EHP
 * 
 */
@RunWith(UnitilsJUnit4TestClassRunner.class)
public class CommonInputValidatorTest {

    /**
     * Test method for
     * {@link be.ehealth.business.mycarenetcommons.validator.CommonInputValidator#validate(be.ehealth.business.mycarenetcommons.domain.CommonInput)}
     * .
     */
    @Test
    public void testValidateEmptyCommonInput() {
        List<ValidationError> expectedValidationErrors = new ArrayList<ValidationError>();
        expectedValidationErrors.add(new ValidationError("commonInput->isTest", null));
        expectedValidationErrors.add(new ValidationError("commonInput->Origin", null));
        expectedValidationErrors.add(new ValidationError("commonInput->InputReference", null));
        try {
            CommonInputValidator.validate(new CommonInput(null, null, null));
            fail("should have thrown ConnectorValidationException");
        } catch (ConnectorValidationException e) {
            List<ValidationError> validationErrors = e.getValidationErrors();
            ReflectionAssert.assertLenientEquals(expectedValidationErrors, validationErrors);
        }

    }

    @Test
    public void testValidCareProviderIndividualNurse() throws Exception {
        CareProvider careProvider = new CareProvider(new Nihii("nurse", "22222222"));
        Identification physicalPerson = new Identification("The Nurse");
        physicalPerson.setSsin("22222222222222");
        careProvider.setPhysicalPerson(physicalPerson);
        CommonInput validInput = new CommonInput(false, new Origin(createValidPackageInfo(), careProvider), "someInputRef");
        CommonInputValidator.validate(validInput);
    }

    @Test
    public void testValidCareProviderGroupOfNurses() throws Exception {
        CareProvider careProvider = new CareProvider(new Nihii("groupofnurses", "22222222"));
        Identification organisation = new Identification("The Group");
        organisation.setNihii(new Nihii("groupofnurses", "22222222222222"));
        careProvider.setOrganization(organisation);
        CommonInput validInput = new CommonInput(false, new Origin(createValidPackageInfo(), careProvider), "someInputRef");
        CommonInputValidator.validate(validInput);
    }

    @Test
    public void testValidPharmacyHolder() throws Exception {
        CareProvider careProvider = new CareProvider(new Nihii("pharmacy-holder", "22222222"));
        Identification organisation = new Identification("The pharmacy");
        organisation.setNihii(new Nihii("pharmacy", "22222222222222"));
        careProvider.setOrganization(organisation);
        Identification physicalPerson = new Identification("The Pharmacy holder");
        physicalPerson.setSsin("333333333333");
        CommonInput validInput = new CommonInput(false, new Origin(createValidPackageInfo(), careProvider), "someInputRef");
        CommonInputValidator.validate(validInput);
    }

    @Test
    public void testValidNonCareProvider() throws Exception {
        Identification organisation = new Identification("ehealth");
        organisation.setCbe("111111111111111");
        Party sender = new Party();
        sender.setOrganization(organisation);
        CommonInput validInput = new CommonInput(false, new Origin(createValidPackageInfo(), sender), "someInputRef");
        CommonInputValidator.validate(validInput);
    }

    @Test
    public void testValidNonCareProviderAndSite() throws Exception {
        Identification organisation = new Identification("ehealth");
        organisation.setCbe("111111111111111");
        Party sender = new Party();
        sender.setOrganization(organisation);
        CommonInput validInput = new CommonInput(false, new Origin(createValidPackageInfo(), "siteId", sender), "someInputRef");
        CommonInputValidator.validate(validInput);
    }

    @Test
    public void testInvalidCareProviderNoPackagePassword() throws Exception {
        List<ValidationError> expectedValidationErrors = new ArrayList<ValidationError>();
        expectedValidationErrors.add(new ValidationError("commonInput->Origin->McnPackageInfo", null));
        PackageInfo packageInfo = createValidPackageInfo();
        packageInfo.setPassword(null);
        CommonInput invalidInput = new CommonInput(false, new Origin(packageInfo, new CareProvider(new Nihii("nurse", "22222222"))), "someInputRef");
        try {
            CommonInputValidator.validate(invalidInput);
        } catch (ConnectorValidationException e) {
            List<ValidationError> validationErrors = e.getValidationErrors();
            ReflectionAssert.assertLenientEquals(expectedValidationErrors, validationErrors);
        }
    }

    @Test
    public void testInvalidCareProviderNoPackageUsername() throws Exception {
        List<ValidationError> expectedValidationErrors = new ArrayList<ValidationError>();
        expectedValidationErrors.add(new ValidationError("commonInput->Origin->McnPackageInfo", null));
        PackageInfo packageInfo = createValidPackageInfo();
        packageInfo.setUserName(null);
        CommonInput invalidInput = new CommonInput(false, new Origin(packageInfo, new CareProvider(new Nihii("nurse", "22222222"))), "someInputRef");
        try {
            CommonInputValidator.validate(invalidInput);
        } catch (ConnectorValidationException e) {
            List<ValidationError> validationErrors = e.getValidationErrors();
            ReflectionAssert.assertLenientEquals(expectedValidationErrors, validationErrors);
        }
    }

    @Test
    public void testInvalidCareProviderNoPackage() throws Exception {
        List<ValidationError> expectedValidationErrors = new ArrayList<ValidationError>();
        expectedValidationErrors.add(new ValidationError("commonInput->Origin->McnPackageInfo", null));
        CommonInput invalidInput = new CommonInput(false, new Origin(null, new CareProvider(new Nihii("nurse", "22222222"))), "someInputRef");
        try {
            CommonInputValidator.validate(invalidInput);
        } catch (ConnectorValidationException e) {
            List<ValidationError> validationErrors = e.getValidationErrors();
            ReflectionAssert.assertLenientEquals(expectedValidationErrors, validationErrors);
        }
    }

    @Test
    public void testInvalidCareProviderNoCareProviderNorSender() throws Exception {
        List<ValidationError> expectedValidationErrors = new ArrayList<ValidationError>();
        expectedValidationErrors.add(new ValidationError("commonInput->Origin", null));
        CommonInput invalidInput = new CommonInput(false, new Origin(createValidPackageInfo(), null, null, null), "someInputRef");
        try {
            CommonInputValidator.validate(invalidInput);
        } catch (ConnectorValidationException e) {
            List<ValidationError> validationErrors = e.getValidationErrors();
            ReflectionAssert.assertLenientEquals(expectedValidationErrors, validationErrors);
        }
    }


    @Test
    public void testInvalidCareProviderEmptyPhysicalPerson() throws Exception {
        List<ValidationError> expectedValidationErrors = new ArrayList<ValidationError>();
        expectedValidationErrors.add(new ValidationError("commonInput->Origin->CareProvider->PhysicalPerson", null));
        CareProvider createCareProvider = new CareProvider(new Nihii("nurse", "22222222"));
        createCareProvider.setPhysicalPerson(new Identification("someName"));
        CommonInput invalidInput = new CommonInput(false, new Origin(createValidPackageInfo(), createCareProvider), "someInputRef");
        try {
            CommonInputValidator.validate(invalidInput);
        } catch (ConnectorValidationException e) {
            List<ValidationError> validationErrors = e.getValidationErrors();
            ReflectionAssert.assertLenientEquals(expectedValidationErrors, validationErrors);
        }
    }

    @Test
    public void testInvalidCareProviderEmptySenderParty() throws Exception {
        List<ValidationError> expectedValidationErrors = new ArrayList<ValidationError>();
        expectedValidationErrors.add(new ValidationError("commonInput->Origin->Sender", null));
        Origin origin = new Origin(createValidPackageInfo(), null, new CareProvider(new Nihii("nurse", "22222222")));
        origin.setSender(new Party());
        CommonInput invalidInput = new CommonInput(false, origin, "someInputRef");
        try {
            CommonInputValidator.validate(invalidInput);
        } catch (ConnectorValidationException e) {
            List<ValidationError> validationErrors = e.getValidationErrors();
            ReflectionAssert.assertLenientEquals(expectedValidationErrors, validationErrors);
        }
    }


    /**
     * @return
     */
    private static PackageInfo createValidPackageInfo() {
        return new PackageInfo("packageName", "userName", "password");
    }


}
