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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.joda.time.DateTime;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import be.ehealth.business.common.domain.Patient;
import be.ehealth.businessconnector.therlink.domain.HcParty;
import be.ehealth.businessconnector.therlink.domain.Proof;
import be.ehealth.businessconnector.therlink.domain.TherapeuticLink;
import be.ehealth.businessconnector.therlink.domain.requests.PutTherapeuticLinkRequest;
import be.ehealth.businessconnector.therlink.domain.responses.PutTherapeuticLinkResponse;
import be.ehealth.businessconnector.therlink.exception.TherLinkBusinessConnectorException;
import be.ehealth.businessconnector.therlink.session.TherlinkSessionServiceFactory;
import be.ehealth.businessconnector.therlink.util.ConfigReader;
import be.ehealth.businessconnector.therlink.util.TestConstants;
import be.ehealth.businessconnector.therlink.util.TherapeuticLinkTypeValues;
import be.ehealth.businessconnector.therlink.util.TherlinkTestUtils;
import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.fgov.ehealth.technicalconnector.tests.session.SessionInitializer;
import be.fgov.ehealth.technicalconnector.tests.utils.AssumeTools;


/**
 * Integration test for therapeutic link requests with a referral author
 * 
 * @author EHP
 * 
 */
@RunWith(Parameterized.class)
public class ReferralRequestsUserIntegrationTest extends AbstractTherlinkIsolationIntegrationTest {

    private static Patient patientFromEid;

    private HcParty referralParty;

    /**
     * @param referralParty
     * @throws TherLinkBusinessConnectorException
     * @throws TechnicalConnectorException
     * @throws InstantiationException
     */
    public ReferralRequestsUserIntegrationTest(Object referralPartyObject) throws TherLinkBusinessConnectorException, TechnicalConnectorException, InstantiationException {
        super();
        referralParty = (HcParty) referralPartyObject;
    }


    @Parameters
    public static Collection<Object[]> data() throws Exception {
        // we need to load the property file already to know which referrals can be tested
        SessionInitializer.init(TestConstants.THERLINK_TEST_PROPERTIES, false);
        ArrayList<Object[]> parameters = new ArrayList<Object[]>();

        for (HcParty referralParty : TherlinkTestUtils.getReferralsToTest()) {
            parameters.add(new Object[]{
                referralParty
            });
        }
        return parameters;

    }

    @BeforeClass
    public static void init() throws Exception {
        AssumeTools.isEIDEnabled();
        SessionInitializer.init(TestConstants.THERLINK_TEST_PROPERTIES);
        patientFromEid = TherlinkTestUtils.getPatientFromEid();
        List<HcParty> allPossibleReferralParties = TherlinkTestUtils.getReferralsToTest();
        TherlinkTestUtils.revokeNonReferrals(patientFromEid);
        // create standard therapeutic link between current user in session and patient
        TherlinkTestUtils.putTherapeuticLinkNonReferral(patientFromEid, ConfigReader.getCareProvider(), null, TherlinkTestUtils.getEidSigningProof(), null);
        TherlinkTestUtils.revokeReferralsForEidPatient(allPossibleReferralParties);

        // String referralNissNumber = choosReferralNissNumberBasedOnCurrentProfessionalType();
        // If pharmacist, we need to create a link with the pharmacy owner
        if (TherlinkTestUtils.getTherapeuticLinkTypeValue().getHcpartyType().equals("perspharmacist")) {
            TherapeuticLink therlinkPharmacyOwner = commonBuilder.createTherapeuticLink(null, null, TherlinkTestUtils.getPatientFromEid(), ConfigReader.getCareProvider().getType(), TherlinkTestUtils.getTherapeuticLinkTypeValue().getTherlinkType(), null, ConfigReader.getCareProvider());

            if (!TherlinkTestUtils.doesLinkExist(therlinkPharmacyOwner)) {
                Proof proof = proofBuilder.createProofForEidReading();
                TherlinkTestUtils.putTherapeuticLinkNonReferral(therlinkPharmacyOwner.getPatient(), therlinkPharmacyOwner.getHcParty(), null, proof, null);
            }
        }
    }

    @AfterClass
    public static void tearDown() throws Exception {

        TherlinkTestUtils.revokeNonReferrals(patientFromEid);
    }


    @After
    public void revokeReferrals() throws Exception {
        TherlinkTestUtils.revokeReferralsForEidPatient(TherlinkTestUtils.getReferralsToTest());
    }


    /**
     * determines if the test should be run for the current type.
     * 
     * @param validTypes the types of TherapeuticLinkValues which are correct for this test.
     * @return
     */
    public boolean shouldTestBeExecuted(TherapeuticLinkTypeValues... validTypes) {
        if (validTypes != null) {
            for (TherapeuticLinkTypeValues validType : Arrays.asList(validTypes)) {
                if (validType.equals(TherlinkTestUtils.getTherapeuticLinkTypeValue())) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Test putTherapeuticLink method Referral case Eid signing proof with a null end date
     */
    @Test
    public void testPutTherapeuticLinkReferralEidSigningWithoutEndDate() throws Exception {
        // there is already a therapeutic link between the current user and the patient ( created in the init method )

        // Create the therapeutic link referral
        String comment = "testing referral to " + referralParty + " without endDate";
        DateTime endDate = null;
        String type = TherlinkTestUtils.getReferralTypeToUse();
        PutTherapeuticLinkRequest createPutTherapeuticLinkRequest = requestObjectBuilder.createPutTherapeuticLinkRequest(endDate, patientFromEid, referralParty, type, comment, TherlinkTestUtils.getEidSigningProof());
        be.fgov.ehealth.hubservices.core.v2.PutTherapeuticLinkRequest mapPutTherapeuticLinkRequest = requestObjectMapper.mapPutTherapeuticLinkRequest(createPutTherapeuticLinkRequest);
        PutTherapeuticLinkResponse putResponse = responseObjectMapper.mapJaxbToPutTherapeuticLinkResponse(TherlinkSessionServiceFactory.getTherlinkService().putTherapeuticLink(mapPutTherapeuticLinkRequest));
        TherlinkTestUtils.validateResponse(null, putResponse);

    }

    /**
     * Test putTherapeuticLink method Referral case Eid signing proof with an end date
     */
    @Test
    public void testPutTherapeuticLinkReferralEidSigningWithEndDate() throws Exception {
        // there is already a therapeutic link between the current user and the patient ( created in the init method )

        // Create the therapeutic link referral
        String comment = "testing referral to " + referralParty;
        // for referral the endDate MUST be startDate + 3 months, otherwise you get an exception
        DateTime endDate = new DateTime().plusMonths(3);
        String type = TherlinkTestUtils.getReferralTypeToUse();
        PutTherapeuticLinkRequest createPutTherapeuticLinkRequest = requestObjectBuilder.createPutTherapeuticLinkRequest(endDate, patientFromEid, referralParty, type, comment, TherlinkTestUtils.getEidSigningProof());
        be.fgov.ehealth.hubservices.core.v2.PutTherapeuticLinkRequest mapPutTherapeuticLinkRequest = requestObjectMapper.mapPutTherapeuticLinkRequest(createPutTherapeuticLinkRequest);
        PutTherapeuticLinkResponse putResponse = responseObjectMapper.mapJaxbToPutTherapeuticLinkResponse(TherlinkSessionServiceFactory.getTherlinkService().putTherapeuticLink(mapPutTherapeuticLinkRequest));
        TherlinkTestUtils.validateResponse(null, putResponse);

    }

}
