/*
 * Copyright (c) eHealth
 */
package be.ehealth.businessconnector.therlink.builders;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import be.ehealth.business.common.domain.Patient;
import be.ehealth.businessconnector.therlink.domain.HcParty;
import be.ehealth.businessconnector.therlink.domain.Proof;
import be.ehealth.businessconnector.therlink.domain.TherapeuticLink;
import be.ehealth.businessconnector.therlink.domain.TherapeuticLinkRequestType;
import be.ehealth.businessconnector.therlink.domain.requests.GetTherapeuticLinkRequest;
import be.ehealth.businessconnector.therlink.domain.requests.PutTherapeuticLinkRequest;
import be.ehealth.businessconnector.therlink.domain.requests.RevokeTherapeuticLinkRequest;
import be.ehealth.businessconnector.therlink.exception.TherLinkBusinessConnectorException;
import be.fgov.ehealth.technicalconnector.tests.session.SessionInitializer;


/**
 * @author Priscilla Colleaux
 * 
 */
public class RequestBuilderImplTest {

    private static RequestObjectBuilder requestObjectBuilder;

    @BeforeClass
    public static void init() throws Exception {
        SessionInitializer.init("/be.ehealth.businessconnector.therlink.test.properties", false);
        requestObjectBuilder = RequestObjectBuilderFactory.getRequestObjectBuilder();
    }


    @Test
    public void createPutTherapeuticLinkRequestGP() throws Exception {
        String linkType = "gpconsultation";
        String linkComment = "comment";
        String patientInss = "91121208397";
        String patientFamilyName = "Strauven";
        String patientFirstName = "Guillaume";
        String hcpFamilyName = "Van Haute";
        String hcpFirstName = "Bart";
        String hcpNihii = "98390860";
        String hcpType = "persphysician";

        Patient patient = new Patient.Builder().withInss(patientInss).withFamilyName(patientFamilyName).withFirstName(patientFirstName).build();

        HcParty concernedHealthCareProfessionel = new HcParty.Builder().withFamilyName(hcpFamilyName).withFirstName(hcpFirstName).withNihii(hcpNihii).withType(hcpType).build();

        PutTherapeuticLinkRequest putTherlinkRequest = requestObjectBuilder.createPutTherapeuticLinkRequest(null, patient, concernedHealthCareProfessionel, linkType, linkComment, (Proof[]) null);

        assertTherapeuticLinkEquals(linkType, linkComment, patient, concernedHealthCareProfessionel, putTherlinkRequest);
    }

    @SuppressWarnings("deprecation")
    private void assertTherapeuticLinkEquals(String linkType, String linkComment, Patient patient, HcParty concernedHealthCareProfessionel, TherapeuticLinkRequestType therlinkRequest) {
        TherapeuticLink link = therlinkRequest.getLink();
        Patient patientLink = link.getPatient();
        Assert.assertEquals(patientLink.getInss().toString(), patient.getInss());
        Assert.assertEquals(patientLink.getLastName(), patient.getLastName());
        Assert.assertEquals(patientLink.getFirstName(), patient.getFirstName());

        HcParty hcPartyLink = link.getHcParty();
        Assert.assertEquals(hcPartyLink.getFamilyName(), concernedHealthCareProfessionel.getFamilyName());
        Assert.assertEquals(hcPartyLink.getFirstName(), concernedHealthCareProfessionel.getFirstName());
        Assert.assertEquals(hcPartyLink.getNihii().toString(), concernedHealthCareProfessionel.getNihii());
        Assert.assertEquals(hcPartyLink.getType(), concernedHealthCareProfessionel.getType());
        Assert.assertEquals(link.getType(), linkType);
        Assert.assertEquals(link.getComment(), linkComment);
    }

    @Test
    public void testCreateRevokeTherapeuticLinkRequestGP() throws Exception {
        String linkType = "gpconsultation";
        String linkComment = "comment";
        String patientInss = "91121208397";
        String patientFamilyName = "Strauven";
        String patientFirstName = "Guillaume";
        String hcpFamilyName = "Van Haute";
        String hcpFirstName = "Bart";
        String hcpNihii = "98390860";
        String hcpType = "persphysician";

        Patient patient = new Patient.Builder().withInss(patientInss).withFamilyName(patientFamilyName).withFirstName(patientFirstName).build();

        HcParty concernedHealthCareProfessionel = new HcParty.Builder().withFamilyName(hcpFamilyName).withFirstName(hcpFirstName).withNihii(hcpNihii).withType(hcpType).build();

        RevokeTherapeuticLinkRequest revokeTherlinkRequest = RequestObjectBuilderFactory.getRequestObjectBuilder().createRevokeTherapeuticLinkRequest(new DateTime(), null, patient, concernedHealthCareProfessionel, linkType, linkComment, (Proof[]) null);

        assertTherapeuticLinkEquals(linkType, linkComment, patient, concernedHealthCareProfessionel, revokeTherlinkRequest);
    }

    @Test
    public void testCreateGetTherapeuticLinkRequestGP() throws Exception {
        String linkType = "gpconsultation";
        String patientInss = "91121208397";
        String patientFamilyName = "Strauven";
        String patientFirstName = "Guillaume";
        String hcpFamilyName = "Van Haute";
        String hcpFirstName = "Bart";
        String hcpNihii = "98390860";
        String hcpType = "persphysician";

        Patient patient = new Patient.Builder().withInss(patientInss).withFamilyName(patientFamilyName).withFirstName(patientFirstName).build();
        HcParty concernedHealthCareProfessionel = new HcParty.Builder().withFamilyName(hcpFamilyName).withFirstName(hcpFirstName).withNihii(hcpNihii).withType(hcpType).build();

        TherapeuticLink query = new TherapeuticLink(patient, concernedHealthCareProfessionel, linkType);

        GetTherapeuticLinkRequest getTherlinkRequest = RequestObjectBuilderFactory.getRequestObjectBuilder().createGetTherapeuticLinkRequest(query, 999, (Proof[]) null);

        assertTherapeuticLinkEquals(linkType, null, patient, concernedHealthCareProfessionel, getTherlinkRequest);
    }

    @Test
    public void testCreateGetTherapeuticLinkRequestGPNoMaxRows() throws Exception {
        String linkType = "gpconsultation";
        String patientInss = "91121208397";
        String patientFamilyName = "Strauven";
        String patientFirstName = "Guillaume";
        String hcpFamilyName = "Van Haute";
        String hcpFirstName = "Bart";
        String hcpNihii = "98390860";
        String hcpType = "persphysician";

        Patient patient = new Patient.Builder().withInss(patientInss).withFamilyName(patientFamilyName).withFirstName(patientFirstName).build();
        HcParty concernedHealthCareProfessionel = new HcParty.Builder().withFamilyName(hcpFamilyName).withFirstName(hcpFirstName).withNihii(hcpNihii).withType(hcpType).build();

        TherapeuticLink query = new TherapeuticLink(patient, concernedHealthCareProfessionel, linkType);

        GetTherapeuticLinkRequest getTherlinkRequest = RequestObjectBuilderFactory.getRequestObjectBuilder().createGetTherapeuticLinkRequest(query, (Proof[]) null);

        assertTherapeuticLinkEquals(linkType, null, patient, concernedHealthCareProfessionel, getTherlinkRequest);
    }

    /**
     * @throws Exception
     */
    @Test
    public void testcreateGetTherapeuticLinkStartDateNotNull() throws Exception {
        String linkType = "gpconsultation";
        String patientInss = "91121208397";
        String patientFamilyName = "Strauven";
        String patientFirstName = "Guillaume";
        String hcpFamilyName = "Van Haute";
        String hcpFirstName = "Bart";
        String hcpNihii = "98390860";
        String hcpType = "persphysician";

        Patient patient = new Patient.Builder().withInss(patientInss).withFamilyName(patientFamilyName).withFirstName(patientFirstName).build();
        HcParty concernedHealthCareProfessionel = new HcParty.Builder().withFamilyName(hcpFamilyName).withFirstName(hcpFirstName).withNihii(hcpNihii).withType(hcpType).build();

        TherapeuticLink query = new TherapeuticLink(patient, concernedHealthCareProfessionel, linkType);

        LocalDate startDate = new LocalDate(2010, 5, 12);
        query.setStartDate(startDate);

        GetTherapeuticLinkRequest getTherlinkRequest = RequestObjectBuilderFactory.getRequestObjectBuilder().createGetTherapeuticLinkRequest(query, 999, (Proof[]) null);

        assertTherapeuticLinkEquals(linkType, null, patient, concernedHealthCareProfessionel, getTherlinkRequest);
    }

    @Test(expected = TherLinkBusinessConnectorException.class)
    public void testcreatePutTherapeuticLinkNull() throws Exception {
        requestObjectBuilder.createPutTherapeuticLinkRequest(null, new Patient(), null, null, null, (Proof[]) null);
    }

    @Test(expected = TherLinkBusinessConnectorException.class)
    public void testcreateGetTherapeuticLinkNull() throws Exception {
        requestObjectBuilder.createGetTherapeuticLinkRequest(null, 999, (Proof[]) null);
    }

    @Test(expected = TherLinkBusinessConnectorException.class)
    public void testcreateRevokeTherapeuticLinkNull() throws Exception {
        requestObjectBuilder.createRevokeTherapeuticLinkRequest(null, null, new Patient(), null, null, null, (Proof[]) null);
    }

    /**
     * A person (patient or hcp) should have - a firstName AND a family name - OR a name But not both a firstname, a family name and name
     */
    @Test
    public void testFirstNameLastNameXORNameDefinedConstraint() throws Exception {
        String patientInss = "91121208397";
        String patientFamilyName = "Strauven";
        String patientFirstName = "Guillaume";
        String hcpFamilyName = "Van Haute";
        String hcpFirstName = "Priscilla";
        String hcpName = "Bart";
        String hcpNihii = "98390860";
        String hcpType = "persphysician";

        new Patient.Builder().withInss(patientInss).withFamilyName(patientFamilyName).withFirstName(patientFirstName).withLastName(patientFamilyName).build();

        new Patient.Builder().withInss(patientInss).withFirstName(patientFirstName).withFamilyName(patientFamilyName).build();

        new HcParty.Builder().withFamilyName(hcpFamilyName).withFirstName(hcpFirstName).withNihii(hcpNihii).withType(hcpType).build();

        new HcParty.Builder().withName(hcpName).withNihii(hcpNihii).withType(hcpType).build();

    }

    @Test(expected = IllegalStateException.class)
    public void testCreatePatientDifferentNames() throws Exception {
        String patientInss = "91121208397";
        String patientFirstName = "Guillaume";
        new Patient.Builder().withInss(patientInss).withFirstName(patientFirstName).build();
    }

    @Test(expected = TherLinkBusinessConnectorException.class)
    public void testCreateHcPartyDifferentNames() throws Exception {
        String hcpFamilyName = "Van Haute";
        String hcpFirstName = "Bart";
        String hcpName = "Bart";
        String hcpNihii = "98390860";
        String hcpType = "persphysician";
        new HcParty.Builder().withFamilyName(hcpFamilyName).withFirstName(hcpFirstName).withNihii(hcpNihii).withName(hcpName).withType(hcpType).build();
    }

}
