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

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

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

import be.ehealth.business.kmehrcommons.CDConsentBuilderUtil;
import be.ehealth.businessconnector.wsconsent.builders.ConsentBuilder;
import be.ehealth.businessconnector.wsconsent.builders.RequestObjectBuilderFactory;
import be.ehealth.businessconnector.wsconsent.utils.TestUtils;
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.ConsentType;
import be.fgov.ehealth.hubservices.core.v2.PatientIdType;
import be.fgov.ehealth.hubservices.core.v2.PutPatientConsentRequest;
import be.fgov.ehealth.hubservices.core.v2.PutPatientConsentResponse;
import be.fgov.ehealth.hubservices.core.v2.RevokePatientConsentRequest;
import be.fgov.ehealth.hubservices.core.v2.RevokePatientConsentResponse;
import be.fgov.ehealth.standards.kmehr.cd.v1.CDCONSENT;
import be.fgov.ehealth.standards.kmehr.cd.v1.CDCONSENTvalues;
import be.fgov.ehealth.standards.kmehr.schema.v1.ErrorType;
import be.fgov.ehealth.technicalconnector.tests.utils.AssumeTools;

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

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

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


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

        ConfigFactory.getConfigValidator().setProperty("endpoint.sts", STS_ENDPOINT);
        ConfigFactory.getConfigValidator().setProperty("endpoint.wsconsent", WSCONSENT_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.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");

        PatientIdType patient = RequestObjectBuilderFactory.getPatientInfoBuilder().readFromEidCard();
        AuthorWithPatientAndPersonType author = RequestObjectBuilderFactory.getAuthorBuilder().readFromEidCard();

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

        // Consent creation
        ConsentBuilder cBuilder = RequestObjectBuilderFactory.getConsentBuilder();
        List<CDCONSENT> cdConsent = new ArrayList<CDCONSENT>();
        cdConsent.add(CDConsentBuilderUtil.createCDConsent("1.0", CDCONSENTvalues.RETROSPECTIVE));
        DateTime signdate = new DateTime(Calendar.getInstance().getTime());
        ConsentType consent = cBuilder.createNewConsent(patient, cdConsent, signdate, null);

        // Get consent service
        WsConsentService service = ServiceFactory.getWsConsentService();
        
        // Put request creation
        PutPatientConsentRequest putConsentRequest = RequestObjectBuilderFactory.getRequestObjectBuilder().createPutRequest(author, consent);
        TestUtils.logJaxbObject(putConsentRequest);

        // Put service call
        PutPatientConsentResponse putConsentResponse = service.putPatientConsent(Session.getInstance().getSession().getSAMLToken(), putConsentRequest);
        TestUtils.logJaxbObject(putConsentResponse);
        checkErrorMessageOrSuccessfull(putConsentResponse, "Consent already exists for the patient");
        
        // Set revoke date
        DateTime revokeDate = new DateTime(Calendar.getInstance().getTime());
        consent.setRevokedate(revokeDate);
        
        // Revoke request creation
        RevokePatientConsentRequest  revokeConsentRequest = RequestObjectBuilderFactory.getRequestObjectBuilder().createRevokeRequest(author, consent);
        TestUtils.logJaxbObject(revokeConsentRequest);
        
        // Revoke service call
        RevokePatientConsentResponse revokeConsentResponse = service.revokePatientConsent(Session.getInstance().getSession().getSAMLToken(), revokeConsentRequest);
        TestUtils.logJaxbObject(revokeConsentResponse);
        checkErrorMessageOrSuccessfull(revokeConsentResponse, "No active consent for the patient");
    }

    protected void checkErrorMessageOrSuccessfull(PutPatientConsentResponse 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 errorMessage = errorMessages[i];
                Assert.assertEquals(errorMessage, secondPutConsentResponse.getAcknowledge().getErrors().get(i).getDescription().getValue());
            }
        }
    }
    
    protected void checkErrorMessageOrSuccessfull(RevokePatientConsentResponse secondRevokeConsentResponse, String... errorMessages) {
        Assert.assertNotNull(secondRevokeConsentResponse);
        Assert.assertNotNull(secondRevokeConsentResponse.getAcknowledge());
        List<ErrorType> errors = secondRevokeConsentResponse.getAcknowledge().getErrors();
        Assert.assertTrue((secondRevokeConsentResponse.getAcknowledge().getErrors().size() == errorMessages.length && !secondRevokeConsentResponse.getAcknowledge().isIscomplete()) || (errors.isEmpty() && secondRevokeConsentResponse.getAcknowledge().isIscomplete()));
        if (!secondRevokeConsentResponse.getAcknowledge().isIscomplete()) {
            for (int i = 0; i < errorMessages.length; i++) {
                String errorMessage = errorMessages[i];
                Assert.assertEquals(errorMessage, secondRevokeConsentResponse.getAcknowledge().getErrors().get(i).getDescription().getValue());
            }
        }
    }

}