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

import java.util.Date;

import org.joda.time.DateTime;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import be.ehealth.business.kmehrcommons.HcPartyUtil;
import be.ehealth.businessconnector.therlink.domain.Proof;
import be.ehealth.businessconnector.therlink.domain.TherapeuticLink;
import be.ehealth.businessconnector.therlink.domain.responses.PutTherapeuticLinkResponse;
import be.ehealth.businessconnector.therlink.domain.responses.TherapeuticLinkResponseError;
import be.ehealth.businessconnector.therlink.exception.TherLinkBusinessConnectorException;
import be.ehealth.businessconnector.therlink.util.ConfigReader;
import be.ehealth.businessconnector.therlink.util.TestConstants;
import be.ehealth.businessconnector.therlink.util.TherlinkTestUtils;
import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.ehealth.technicalconnector.session.Session;
import be.fgov.ehealth.technicalconnector.tests.session.SessionInitializer;


/**
 * @author EH076
 * 
 *         Usage integration tests for {@link TherLinkService} (requires eid card and pin code input)
 * 
 *         Some use case for common usage of the connector
 * 
 *         This test does not depend on the existence of therapeutic links in the test environment. this test will use the standard offline
 *         patient ( configured in test property file ) for the tests and the standard careprovider from the config.
 * 
 */
@SuppressWarnings("deprecation")
public class TherLinkServiceUsageIntegrationTest extends AbstractTherlinkIsolationIntegrationTest {

    /**
     * @throws TherLinkBusinessConnectorException
     * @throws TechnicalConnectorException
     * @throws InstantiationException
     */
    public TherLinkServiceUsageIntegrationTest() throws TherLinkBusinessConnectorException, TechnicalConnectorException, InstantiationException {
        super();
    }


    private static final Logger LOGGER = LoggerFactory.getLogger(TherLinkServiceUsageIntegrationTest.class);

    @Before
    @After
    public void init() throws Exception {
        Session.getInstance().unloadSession();
        SessionInitializer.init(TestConstants.THERLINK_TEST_PROPERTIES);
        TherlinkTestUtils.revokeNonReferrals(TherlinkTestUtils.getOfflinePatient());
        Thread.sleep(1000);
    }

    /**
     * Test putTherapeuticLink method with eid reading proof with an end date
     * 
     * Try to put the same link twice
     * 
     */
    @Test
    public void testDuplicatePutTherapeuticLinkEidReadingProofWithEndDate() throws Exception {
        TherapeuticLink therlink = commonBuilder.createTherapeuticLink(TherlinkTestUtils.getOfflinePatient(), HcPartyUtil.getAuthorKmehrQuality(), TherlinkTestUtils.getTherapeuticLinkTypeValue().getTherlinkType(), new Date(), new DateTime().plusMonths(6).toDate(), null, ConfigReader.getCareProvider());
        PutTherapeuticLinkResponse response = TherlinkTestUtils.putTherapeuticLinkNonReferral(therlink.getPatient(), therlink.getHcParty(), null, proofBuilder.createProofForEidReading(), null);
        Assert.assertTrue(response.getAcknowledge().isComplete());
        if (!TherlinkTestUtils.doesLinkExist(therlink)) {
            Assert.fail("link not created");
        }
        // Try to put the same link a second time
        // This time we are expecting an error

        PutTherapeuticLinkResponse putResponse = TherlinkTestUtils.putTherapeuticLinkNonReferral(therlink.getPatient(), therlink.getHcParty(), null, proofBuilder.createProofForEidReading(), "NIP.META.TlServiceBean");
        if (putResponse.getAcknowledge().isComplete()) {
            LOGGER.info(">>> Duplicate therapeutic link could be put : we should have an error");
            Assert.fail("Duplicate therapeuticLink worked : we should have got an error");
        } else {
            LOGGER.info("Duplicate therapeuticLink didn't work : OK");
        }

    }

    /**
     * Test putTherapeuticLink method with eid reading proof with an end date
     */
    @Test
    public void testPutTherapeuticLinkEidReadingProofWithEndDate() throws Exception {
        TherapeuticLink therlink = commonBuilder.createTherapeuticLink(TherlinkTestUtils.getOfflinePatient(), HcPartyUtil.getAuthorKmehrQuality(), TherlinkTestUtils.getTherapeuticLinkTypeValue().getTherlinkType(), new Date(), new DateTime().plusMonths(6).toDate(), null, ConfigReader.getCareProvider());
        PutTherapeuticLinkResponse response = TherlinkTestUtils.putTherapeuticLinkNonReferral(therlink.getPatient(), therlink.getHcParty(), null, proofBuilder.createProofForEidReading(), null);
        Assert.assertTrue(response.getAcknowledge() != null && response.getAcknowledge().isComplete());
        if (!TherlinkTestUtils.doesLinkExist(therlink)) {
            Assert.fail("link not created");
        }

    }

    /**
     * Test putTherapeuticLink method with eid reading proof with a null end date
     */
    @Test
    public void testPutTherapeuticLinkEidReadingProofWithoutStartAndEndDate() throws Exception {
        TherapeuticLink therlink = commonBuilder.createTherapeuticLink(TherlinkTestUtils.getOfflinePatient(), HcPartyUtil.getAuthorKmehrQuality(), TherlinkTestUtils.getTherapeuticLinkTypeValue().getTherlinkType(), null, null, null, ConfigReader.getCareProvider());
        if (TherlinkTestUtils.doesLinkExist(therlink)) {
            revokeLink(therlink);
        }
        therlink.setEndDate(null);
        PutTherapeuticLinkResponse response = TherlinkTestUtils.putTherapeuticLinkNonReferral(therlink.getPatient(), therlink.getHcParty(), null, proofBuilder.createProofForEidReading(), null);
        Assert.assertTrue(response.getAcknowledge() != null && response.getAcknowledge().isComplete());
        if (!TherlinkTestUtils.doesLinkExist(therlink)) {
            Assert.fail("link not created");
        }
    }

    /**
     * Test putTherapeuticLink method with sis reading proof with an end date
     */
    @Test
    // @Ignore("remove this test end 2016 : sis cards valid till end of 2016 , i did not found a valid sis card in our test persons")
    public void testPutTherapeuticLinkSisReadingProofWithEndDate() throws Exception {
        TherapeuticLink therlink = commonBuilder.createTherapeuticLink(TherlinkTestUtils.getOfflinePatient(), HcPartyUtil.getAuthorKmehrQuality(), TherlinkTestUtils.getTherapeuticLinkTypeValue().getTherlinkType(), new Date(), new DateTime().plusMonths(6).toDate(), null, ConfigReader.getCareProvider());

        if (TherlinkTestUtils.doesLinkExist(therlink)) {
            revokeLink(therlink);
        }
        Proof proof = proofBuilder.createProofForSisReading();
        PutTherapeuticLinkResponse response = TherlinkTestUtils.putTherapeuticLinkNonReferral(therlink.getPatient(), therlink.getHcParty(), null, proof, "IDS2.INPUT.70");
        Assert.assertTrue(response.getAcknowledge() != null && response.getAcknowledge().getListOfErrors() != null);
        Assert.assertEquals(1, response.getAcknowledge().getListOfErrors().size());
        TherapeuticLinkResponseError therapeuticLinkResponseError = response.getAcknowledge().getListOfErrors().get(0);
        Assert.assertEquals("IDS2.INPUT.70", therapeuticLinkResponseError.getErrorCode());
    }

    /**
     * Test putTherapeuticLink method with sis reading proof with a null end date
     */
    @Test
    // @Ignore("remove this test end 2016 : sis cards valid till end of 2016 , i did not found a valid sis card in our test persons")
    public void testPutTherapeuticLinkSisReadingProofWithoutEndDate() throws Exception {
        TherapeuticLink therlink = commonBuilder.createTherapeuticLink(null, null, TherlinkTestUtils.getOfflinePatient(), HcPartyUtil.getAuthorKmehrQuality(), TherlinkTestUtils.getTherapeuticLinkTypeValue().getTherlinkType(), null, ConfigReader.getCareProvider());

        if (TherlinkTestUtils.doesLinkExist(therlink)) {
            revokeLink(therlink);
        }
        therlink.setEndDate(null);
        Proof proof = proofBuilder.createProofForSisReading();
        // test should now return that the sis card is not valid anymore
        PutTherapeuticLinkResponse response = TherlinkTestUtils.putTherapeuticLinkNonReferral(therlink.getPatient(), therlink.getHcParty(), null, proof, "IDS2.INPUT.70");
        Assert.assertTrue(response.getAcknowledge() != null && response.getAcknowledge().getListOfErrors() != null);
        Assert.assertEquals(1, response.getAcknowledge().getListOfErrors().size());
        TherapeuticLinkResponseError therapeuticLinkResponseError = response.getAcknowledge().getListOfErrors().get(0);
        Assert.assertEquals("IDS2.INPUT.70", therapeuticLinkResponseError.getErrorCode());
    }


}
