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

import java.util.Calendar;
import java.util.List;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.Test;

import be.ehealth.business.kmehrcommons.HcPartyUtil;
import be.ehealth.businessconnector.therlink.session.TherLinkService;
import be.ehealth.businessconnector.therlink.session.TherlinkSessionServiceFactory;
import be.ehealth.technicalconnector.beid.BeIDInfo;
import be.ehealth.technicalconnector.beid.domain.Identity;
import be.ehealth.technicalconnector.config.ConfigFactory;
import be.ehealth.technicalconnector.session.Session;
import be.ehealth.technicalconnector.session.SessionItem;
import be.fgov.ehealth.hubservices.core.v2.AuthorWithPatientAndPersonType;
import be.fgov.ehealth.hubservices.core.v2.HCPartyIdType;
import be.fgov.ehealth.hubservices.core.v2.PatientIdType;
import be.fgov.ehealth.hubservices.core.v2.PutTherapeuticLinkRequest;
import be.fgov.ehealth.hubservices.core.v2.PutTherapeuticLinkResponse;
import be.fgov.ehealth.hubservices.core.v2.RequestType;
import be.fgov.ehealth.hubservices.core.v2.TherapeuticLinkType;
import be.fgov.ehealth.standards.kmehr.cd.v1.CDHCPARTYschemes;
import be.fgov.ehealth.standards.kmehr.cd.v1.CDTHERAPEUTICLINK;
import be.fgov.ehealth.standards.kmehr.cd.v1.CDTHERAPEUTICLINKschemes;
import be.fgov.ehealth.standards.kmehr.id.v1.IDHCPARTYschemes;
import be.fgov.ehealth.standards.kmehr.id.v1.IDKMEHR;
import be.fgov.ehealth.standards.kmehr.id.v1.IDKMEHRschemes;
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.ErrorType;
import be.fgov.ehealth.standards.kmehr.schema.v1.HcpartyType;
import be.fgov.ehealth.technicalconnector.tests.utils.AssumeTools;

/**
 * Production test with eid
 * 
 * @author EHP
 */
public class TherlinkServiceEidCertificateIntegrationTest {

    private static final String STS_ENDPOINT = "https://services-acpt.ehealth.fgov.be/IAM/Saml11TokenService/v1";

    private static final String THERLINK_ENDPOINT = "https://services-acpt.ehealth.fgov.be/TherLink/v1";

    private static final String HCP_NISS = null; // nullable

    private static final String HCP_NIHII = "49438821408";

    private static final String HCP_PROFESSION = "persnurse";

    private static final String HCP_FIRSTNAME = "Annik";

    private static final String HCP_LASTNAME = "Dupont";

    private static final String THERLINK_TYPE = "patientmanagement";

    private static final String COMMENT = "Test WS Patient";

    private static Identity identity;

    @Test
    public void testFullScenario() throws Exception {
        AssumeTools.isEIDEnabled();
        identity = BeIDInfo.getInstance("patient").getIdentity();

        ConfigFactory.getConfigValidator().setProperty("endpoint.sts", STS_ENDPOINT);
        ConfigFactory.getConfigValidator().setProperty("endpoint.therlink", THERLINK_ENDPOINT);

        ConfigFactory.getConfigValidator().setProperty("sessionmanager.samlattribute.1", "urn:be:fgov:identification-namespace,urn:be:fgov:ehealth:1.0:certificateholder:person:ssin," + identity.getNationalNumber());
        ConfigFactory.getConfigValidator().setProperty("sessionmanager.samlattribute.2", "urn:be:fgov:identification-namespace,urn:be:fgov:person:ssin," + identity.getNationalNumber());
        ConfigFactory.getConfigValidator().setProperty("sessionmanager.samlattribute.3", null);
        ConfigFactory.getConfigValidator().setProperty("sessionmanager.samlattributedesignator.1", "urn:be:fgov:identification-namespace,urn:be:fgov:ehealth:1.0:certificateholder:person:ssin");
        ConfigFactory.getConfigValidator().setProperty("sessionmanager.samlattributedesignator.2", "urn:be:fgov:identification-namespace,urn:be:fgov:person:ssin");
        ConfigFactory.getConfigValidator().setProperty("sessionmanager.samlattributedesignator.3", null);

        // Patient creation based on Eid
        IDPATIENT idPatient = new IDPATIENT();
        idPatient.setS(IDPATIENTschemes.INSS);
        idPatient.setSV("1.0");
        idPatient.setValue(identity.getNationalNumber());

        PatientIdType patient = new PatientIdType();
        patient.getIds().add(idPatient);
        patient.setFirstname(identity.getFirstName());
        patient.setFamilyname(identity.getName());

        // Author creation
        AuthorWithPatientAndPersonType author = new AuthorWithPatientAndPersonType();

        HcpartyType hcParty = new HcpartyType();
        hcParty.getCds().add(HcPartyUtil.buildCd("1.1", "application", CDHCPARTYschemes.CD_HCPARTY, null));
        hcParty.getIds().add(HcPartyUtil.buildId("1.0", "1990000332", IDHCPARTYschemes.LOCAL));
        hcParty.setName("eHealth TherLink Connector");
        author.getHcparties().add(hcParty);
        author.setPatient(patient);

        // Session creation
        SessionItem session = Session.getInstance().createSessionEidOnly();
        Assert.assertNotNull(session.getSAMLToken());

        // HCP creation
        HCPartyIdType hcp = new HCPartyIdType();
        if(HCP_NISS != null){
            hcp.getIds().add(HcPartyUtil.buildId("1.0", HCP_NISS, IDHCPARTYschemes.INSS));
        }
        hcp.getIds().add(HcPartyUtil.buildId("1.0", HCP_NIHII, IDHCPARTYschemes.ID_HCPARTY));
        hcp.setCd(HcPartyUtil.buildCd("1.1", HCP_PROFESSION, CDHCPARTYschemes.CD_HCPARTY, null));
        hcp.setFirstname(HCP_FIRSTNAME);
        hcp.setFamilyname(HCP_LASTNAME);

        // Therlink type creation
        CDTHERAPEUTICLINK therlinkType = new CDTHERAPEUTICLINK();
        therlinkType.setS(CDTHERAPEUTICLINKschemes.CD_THERAPEUTICLINKTYPE);
        therlinkType.setSV("1.1");
        therlinkType.setValue(THERLINK_TYPE);

        // Request header creation
        RequestType requestType = new RequestType();

        IDKMEHR id = new IDKMEHR();
        id.setSV("1.0");
        id.setS(IDKMEHRschemes.ID_KMEHR);
        id.setValue("1990000332." + UUID.randomUUID());

        requestType.setId(id);
        requestType.setAuthor(author);
        requestType.setDate(new DateTime(Calendar.getInstance().getTime()));
        requestType.setTime(new DateTime(Calendar.getInstance().getTime()));

        // Request creation
        TherapeuticLinkType therlink = new TherapeuticLinkType();
        therlink.setPatient(patient);
        therlink.getHcparties().add(hcp);
        therlink.setCd(therlinkType);
        therlink.setComment(COMMENT);

        Calendar cal = Calendar.getInstance();
        therlink.setStartdate(new DateTime(cal.getTime()));
        cal.add(Calendar.MONTH, 15);
        therlink.setEnddate(new DateTime(cal.getTime()));

        PutTherapeuticLinkRequest request = new PutTherapeuticLinkRequest();
        request.setRequest(requestType);
        request.setTherapeuticlink(therlink);

        // Service call
        TherLinkService service = TherlinkSessionServiceFactory.getTherlinkService();
        PutTherapeuticLinkResponse response = service.putTherapeuticLink(request);

        checkErrorMessageOrSuccessfull(response, "a valid therapeutic link exists");
    }

    protected void checkErrorMessageOrSuccessfull(PutTherapeuticLinkResponse secondPutConsentResponse, String... errorMessages) {
        Assert.assertNotNull(secondPutConsentResponse);
        Assert.assertNotNull(secondPutConsentResponse.getAcknowledge());
        List<ErrorType> errors = secondPutConsentResponse.getAcknowledge().getErrors();
        Assert.assertTrue((secondPutConsentResponse.getAcknowledge().getErrors().size() == errorMessages.length && !secondPutConsentResponse.getAcknowledge().isIscomplete()) || (errors.isEmpty() && secondPutConsentResponse.getAcknowledge().isIscomplete()));
        if (!secondPutConsentResponse.getAcknowledge().isIscomplete()) {
            for (int i = 0; i < errorMessages.length; i++) {
                String errorMessageSearched = errorMessages[i];
                String errorMessageResponse = secondPutConsentResponse.getAcknowledge().getErrors().get(i).getDescription().getValue();
                Assert.assertTrue("Search after '" + errorMessageSearched + "' in the error message but have '" + errorMessageResponse + "'", StringUtils.contains(errorMessageResponse, errorMessageSearched));
            }
        }
    }
}