/*
 * Copyright (c) eHealth
 */
package be.ehealth.businessconnector.dmg.session;

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

import org.joda.time.DateTime;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import be.ehealth.business.common.domain.Patient;
import be.ehealth.business.mycarenetcommons.helper.ErrorMyCarenetTypeManagement;
import be.ehealth.businessconnector.dmg.builders.RequestObjectBuilder;
import be.ehealth.businessconnector.dmg.builders.RequestObjectBuilderFactory;
import be.ehealth.businessconnector.dmg.builders.ResponseObjectBuilder;
import be.ehealth.businessconnector.dmg.builders.ResponseObjectBuilderFactory;
import be.ehealth.businessconnector.dmg.domain.DMGReferences;
import be.ehealth.businessconnector.dmg.domain.DmgBuilderResponse;
import be.ehealth.technicalconnector.config.ConfigFactory;
import be.ehealth.technicalconnector.session.Session;
import be.ehealth.technicalconnector.utils.ConnectorIOUtils;
import be.ehealth.technicalconnector.utils.ConnectorXmlUtils;
import be.ehealth.technicalconnector.utils.MarshallerHelper;
import be.fgov.ehealth.globalmedicalfile.protocol.v1.ConsultGlobalMedicalFileRequest;
import be.fgov.ehealth.globalmedicalfile.protocol.v1.SendResponseType;
import be.fgov.ehealth.messageservices.core.v1.AcknowledgeType;
import be.fgov.ehealth.messageservices.core.v1.PatientType;
import be.fgov.ehealth.messageservices.core.v1.RetrieveTransactionResponse;
import be.fgov.ehealth.messageservices.core.v1.SelectRetrieveTransaction;
import be.fgov.ehealth.standards.kmehr.id.v1.IDINSURANCE;
import be.fgov.ehealth.standards.kmehr.id.v1.IDPATIENT;
import be.fgov.ehealth.standards.kmehr.id.v1.IDPATIENTschemes;
import be.fgov.ehealth.standards.kmehr.schema.v1.ErrorMyCarenetType;
import be.fgov.ehealth.standards.kmehr.schema.v1.MemberinsuranceType;
import be.fgov.ehealth.technicalconnector.tests.session.SessionInitializer;

/**
 * Consult Integration Test
 * 
 * @author EHP
 * 
 */
public class DmgConsultationIntegrationTest {

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

    @BeforeClass
    public static void init() throws Exception {
        LOG.debug("DmgConsultationIntegrationTest.loadSession:");
        SessionInitializer.init("/be.ehealth.businessconnector.dmg.test.properties");
        ConfigFactory.getConfigValidator().setProperty("be.ehealth.businessconnector.dmg.builders.impl.dumpMessages", "true");
    }

    @AfterClass
    public static void tearDown() throws Exception {
        Session.getInstance().unloadSession();
    }

    @Test
    public final void testOA100() throws Exception {
        baseConsultationTest("Paul", "Velter", "100", null, "55052650995", new DateTime());
    }

    @Test
    public final void testOA300() throws Exception {
        baseConsultationTest("Madeleine", "De Maret", "300", null, "59120346292", new DateTime());
    }

    @Test
    public final void testOA500() throws Exception {
        // therapeutic link exists for Priscilla s doctor for this patient
        baseConsultationTest("Anna", "Lewandowska", "500", null, "79022050484", new DateTime());
    }


    @Test
    public final void testOA600() throws Exception {
        baseConsultationTest("Ajse", "Osmani", "600", null, "05041001640", new DateTime());
    }

    @Test
    public final void testOA900() throws Exception {
        baseConsultationTest("Yves", "Matagne", "900", null, "70032040303", new DateTime());
    }


    private void baseConsultationTest(String firstname, String lastName, String mutuality, String regNrWithMut, String inss, DateTime dmgStartDate) throws Exception {
        Boolean istest = true;

        // DMGReferences ref = DmgTestUtils.createDmgReferenceForTest();
        DMGReferences ref = new DMGReferences(true);


        Patient pI = new Patient();
        pI.setFirstName(firstname);
        pI.setLastName(lastName);
        pI.setMutuality(mutuality);
        pI.setRegNrWithMut(regNrWithMut);
        pI.setInss(inss);

        DateTime dateReference = new DateTime();
        byte[] expected = ConnectorIOUtils.getBytes(ConnectorIOUtils.getResourceAsStream("/templates/RetrieveTransactionRequest.select.xml"));

        MarshallerHelper<SelectRetrieveTransaction, SelectRetrieveTransaction> kmehrRequestMarshaller = new MarshallerHelper<SelectRetrieveTransaction, SelectRetrieveTransaction>(SelectRetrieveTransaction.class, SelectRetrieveTransaction.class);
        SelectRetrieveTransaction request = kmehrRequestMarshaller.toObject(expected);


        PatientType patient = new PatientType();
        IDPATIENT idpatient = new IDPATIENT();

        if (inss != null && !inss.isEmpty()) {
            idpatient.setSV("1.0");
            idpatient.setValue(pI.getInss());
            idpatient.setS(IDPATIENTschemes.ID_PATIENT);
            patient.getIds().add(idpatient);
        }

        MemberinsuranceType member = new MemberinsuranceType();

        if (pI.getRegNrWithMut() != null) {
            member.setMembership(pI.getRegNrWithMut());
            if (pI.getMutuality() != null) {
                IDINSURANCE id = new IDINSURANCE();
                id.setSV("1.0");
                id.setValue(pI.getMutuality());
                member.setId(id);
            }
        }
        if (member.getId() != null || member.getMembership() != null) {
            patient.setInsurancymembership(member);
        }


        request.setPatient(patient);
        request.getTransaction().setBegindate(dmgStartDate);


        RequestObjectBuilder builder = RequestObjectBuilderFactory.getRequestObjectBuilder();
        ConsultGlobalMedicalFileRequest result = builder.buildSendConsultRequest(istest, ref, pI, dateReference, request);

        ConnectorXmlUtils.logXmlObject(result);

        DmgService service = DmgSessionServiceFactory.getDmgService();
        SendResponseType resp = service.consultGlobalMedicalFile(result);


        ResponseObjectBuilder respBuilder = ResponseObjectBuilderFactory.getResponseObjectBuilder();
        DmgBuilderResponse response = respBuilder.handleSendResponseType(resp);

        Assert.assertEquals("Status code not 200", "200", response.getEhealthStatus());

        RetrieveTransactionResponse retrieveTransactionResponse = response.getRetrieveTransactionResponse();
        Assert.assertNotNull(retrieveTransactionResponse);
        AcknowledgeType acknowledge = retrieveTransactionResponse.getAcknowledge();
        Assert.assertNotNull(acknowledge);

        List<ErrorMyCarenetType> errors = acknowledge.getErrors();
        Assert.assertTrue(ErrorMyCarenetTypeManagement.printErrors(errors), errors.isEmpty());

        if (retrieveTransactionResponse.getKmehrmessage() == null) {
            LOG.warn("EMPTY RETURN MESSAGE");
        }

        Map<String, Object> resultMap = response.getResult();
        Assert.assertNotNull(resultMap.get(DmgBuilderResponse.RESULT_AS_BYTE));
        Assert.assertNotNull(resultMap.get(DmgBuilderResponse.RESULT_EHEALTH_STATUS));
        Assert.assertNotNull(resultMap.get(DmgBuilderResponse.RESULT_HAS_SIGNATURE));
        Assert.assertNotNull(resultMap.get(DmgBuilderResponse.RESULT_ORGINAL));
        Assert.assertNull(resultMap.get(DmgBuilderResponse.RESULT_SIGINATURE_VERIFICATION));
        Assert.assertEquals("200", resultMap.get(DmgBuilderResponse.RESULT_EHEALTH_STATUS));
        Assert.assertEquals(false, resultMap.get(DmgBuilderResponse.RESULT_HAS_SIGNATURE));

    }

}
