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

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

import org.joda.time.DateTime;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import be.ehealth.business.kmehrcommons.CDConsentBuilderUtil;
import be.ehealth.businessconnector.wsconsent.exception.WsConsentBusinessConnectorException;
import be.ehealth.businessconnector.wsconsent.utils.TestUtils;
import be.ehealth.technicalconnector.config.ConfigFactory;
import be.ehealth.technicalconnector.config.ConfigValidator;
import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.ehealth.technicalconnector.idgenerator.IdGeneratorFactory;
import be.ehealth.technicalconnector.session.Session;
import be.ehealth.technicalconnector.testcommons.idgenerator.FixedValueIdGenerator;
import be.fgov.ehealth.hubservices.core.v2.AuthorWithPatientType;
import be.fgov.ehealth.hubservices.core.v2.ConsentType;
import be.fgov.ehealth.hubservices.core.v2.GetPatientConsentRequest;
import be.fgov.ehealth.hubservices.core.v2.PatientIdType;
import be.fgov.ehealth.hubservices.core.v2.PutPatientConsentRequest;
import be.fgov.ehealth.hubservices.core.v2.RevokePatientConsentRequest;
import be.fgov.ehealth.hubservices.core.v2.SelectGetPatientConsentType;
import be.fgov.ehealth.standards.kmehr.cd.v1.CDCONSENT;
import be.fgov.ehealth.standards.kmehr.cd.v1.CDCONSENTvalues;
import be.fgov.ehealth.technicalconnector.tests.session.SessionInitializer;
import be.fgov.ehealth.technicalconnector.tests.utils.TestPropertiesLoader;


/**
 * test the creation of the Request jaxb objects.
 * 
 * @author EHP
 * 
 * 
 * 
 */
public class RequestObjectBuilderTest {


    private String originalIdGeneratorClassName;


    @BeforeClass
    public static void init() throws Exception {
        // only integration tests need to run for all professionTypes
        Assume.assumeTrue("persphysician".equals(TestPropertiesLoader.getProperties("/be.ehealth.businessconnector.wsconsent.test.properties").getProperty("session.professionType")));
        SessionInitializer.init("/be.ehealth.businessconnector.wsconsent.test.properties", false);
    }

    @Before
    public void initializeDummyIdGenerator() {
        String key = IdGeneratorFactory.PROPS_IDGENERATOR_PREFIX + "default" + IdGeneratorFactory.PROPS_IDGENERATOR_SUFFIX;
        ConfigValidator configValidator = ConfigFactory.getConfigValidator(new ArrayList<String>());
        originalIdGeneratorClassName = configValidator.getProperty(key);
        configValidator.setProperty(key, FixedValueIdGenerator.class.getCanonicalName());
        IdGeneratorFactory.invalidateCachedInstance();
    }

    @After
    public void restoreIdGenerator() {
        String key = IdGeneratorFactory.PROPS_IDGENERATOR_PREFIX + "default" + IdGeneratorFactory.PROPS_IDGENERATOR_SUFFIX;
        ConfigValidator configValidator = ConfigFactory.getConfigValidator(new ArrayList<String>());
        if (originalIdGeneratorClassName != null) {
            configValidator.setProperty(key, originalIdGeneratorClassName);
        }
        IdGeneratorFactory.invalidateCachedInstance();
    }

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


    @Test
    public void testCreatePutRequest() throws Exception {

        PatientIdType patient = TestUtils.createDummyPatient();
        List<CDCONSENT> consentList = new ArrayList<CDCONSENT>();
        consentList.add(CDConsentBuilderUtil.createCDConsent("1.0", CDCONSENTvalues.RETROSPECTIVE));
        ConsentType consentType = RequestObjectBuilderFactory.getConsentBuilder().createNewConsent(patient, consentList, null, null);
        AuthorWithPatientType author = RequestObjectBuilderFactory.getAuthorBuilder().createAuthor();

        AuthorWithPatientType authorwithpatient = new AuthorWithPatientType();
        authorwithpatient.getHcparties().addAll(author.getHcparties());

        consentType.setPatient(patient);
        consentType.setSigndate(new DateTime(2013, 5, 15, 0, 0, 0, 0));
        consentType.setAuthor(authorwithpatient);

        PutPatientConsentRequest consentRequest = RequestObjectBuilderFactory.getRequestObjectBuilder().createPutRequest(authorwithpatient, consentType);
        TestUtils.logJaxbObject(consentRequest);
        TestUtils.assertXmlSimular("/expected/putRequest.xml", consentRequest);
    }

    @Test(expected = WsConsentBusinessConnectorException.class)
    public void testCreatePutRequestWithNoConsent() throws Exception {
        AuthorWithPatientType author = RequestObjectBuilderFactory.getAuthorBuilder().createAuthor();

        AuthorWithPatientType authorwithpatient = new AuthorWithPatientType();
        authorwithpatient.getHcparties().addAll(author.getHcparties());


        PutPatientConsentRequest consentRequest = RequestObjectBuilderFactory.getRequestObjectBuilder().createPutRequest(authorwithpatient, null);

        Assert.assertNotNull(consentRequest);
    }

    @Test(expected = WsConsentBusinessConnectorException.class)
    public void testCreatePutRequestWithNoAuthorwithpatient() throws Exception {

        PatientIdType patient = TestUtils.createDummyPatient();
        List<CDCONSENT> consentList = new ArrayList<CDCONSENT>();
        consentList.add(CDConsentBuilderUtil.createCDConsent("1.0", CDCONSENTvalues.RETROSPECTIVE));
        ConsentType consentType = RequestObjectBuilderFactory.getConsentBuilder().createNewConsent(patient, consentList, null, null);
        consentType.setPatient(patient);
        consentType.setSigndate(new DateTime(2013, 5, 15, 0, 0, 0, 0));

        RequestObjectBuilderFactory.getRequestObjectBuilder().createPutRequest(null, consentType);
    }


    @Test
    public void testCreateRevokeRequest() throws Exception {

        PatientIdType patient = TestUtils.createDummyPatient();
        AuthorWithPatientType author = RequestObjectBuilderFactory.getAuthorBuilder().createAuthor();
        ConsentType consentType = createDummyRevokeConsent(patient, author);

        AuthorWithPatientType authorwithpatient = new AuthorWithPatientType();
        authorwithpatient.getHcparties().addAll(author.getHcparties());

        consentType.setAuthor(authorwithpatient);
        consentType.setPatient(patient);
        consentType.setSigndate(new DateTime(2013, 8, 8, 0, 0, 0, 0));
        consentType.setRevokedate(new DateTime(2013, 8, 8, 0, 0, 0, 0));

        RevokePatientConsentRequest consentRequest = RequestObjectBuilderFactory.getRequestObjectBuilder().createRevokeRequest(authorwithpatient, consentType);

        TestUtils.logJaxbObject(consentRequest);
        TestUtils.assertXmlSimular("/expected/revokeRequest.xml", consentRequest);
    }


    /**
     * @param patient
     * @param author
     * @return
     * @throws TechnicalConnectorException
     * @throws WsConsentBusinessConnectorException
     * @throws InstantiationException
     */
    private ConsentType createDummyRevokeConsent(PatientIdType patient, AuthorWithPatientType author) throws TechnicalConnectorException, WsConsentBusinessConnectorException, InstantiationException {
        List<CDCONSENT> consentList = new ArrayList<CDCONSENT>();
        consentList.add(CDConsentBuilderUtil.createCDConsent("1.0", CDCONSENTvalues.RETROSPECTIVE));
        ConsentType consentType = RequestObjectBuilderFactory.getConsentBuilder().createNewConsent(patient, consentList, new DateTime(), author);
        consentType.setRevokedate(new DateTime());
        return consentType;
    }

    @Test
    public void testCreateGetRequest() throws Exception {

        PatientIdType patient = TestUtils.createDummyPatient();
        List<CDCONSENT> consentList = new ArrayList<CDCONSENT>();
        consentList.add(CDConsentBuilderUtil.createCDConsent("1.0", CDCONSENTvalues.RETROSPECTIVE));
        SelectGetPatientConsentType consentType = RequestObjectBuilderFactory.getConsentBuilder().createSelectGetPatientConsent(patient, consentList);
        AuthorWithPatientType author = RequestObjectBuilderFactory.getAuthorBuilder().createAuthor();

        AuthorWithPatientType authorwithpatient = new AuthorWithPatientType();
        authorwithpatient.getHcparties().addAll(author.getHcparties());

        consentType.setPatient(patient);

        GetPatientConsentRequest consentRequest = RequestObjectBuilderFactory.getRequestObjectBuilder().createGetRequest(authorwithpatient, consentType);
        TestUtils.logJaxbObject(consentRequest);
        TestUtils.assertXmlSimular("/expected/getRequest.xml", consentRequest);

    }


}
