package com.agilex.healthcare.schedulingmanager.resources;


import com.agilex.healthcare.mobilehealthplatform.domain.PatientSearchResults;
import com.agilex.healthcare.mobilehealthplatform.domain.Patients;
import com.agilex.healthcare.mobilehealthplatform.domain.ResourceDirectory;
import com.agilex.healthcare.schedulingmanager.clientapi.MobileHealthClientTestVersion;
import com.agilex.healthcare.schedulingmanager.domain.BookedAppointments;
import com.agilex.healthcare.schedulingmanager.domain.WaitListEntries;
import com.agilex.healthcare.schedulingmanager.testutility.IntegrationTestConfiguration;
import com.agilex.healthcare.schedulingmanager.testutility.TestHelper;
import com.agilex.healthcare.utility.ModeHelper;
import com.agilex.healthcare.utility.XpathHelper;
import org.junit.*;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import javax.ws.rs.core.UriBuilder;
import java.net.URI;

import static org.junit.Assert.*;

public class WaitListResourceTest
{
    private static String mhpResourceUri;
    private static MobileHealthClientTestVersion client;
    private static Node patientLinkNode;
    private static Node schedulingResourceDirectoryLinkNode;
    private static String startDate = "09/09/2013";
    private static String deleteTokenURI = null;

    @BeforeClass
    public static void startUp(){
        Assume.assumeTrue(ModeHelper.isMode("va-provider-prod"));
        client = TestHelper.createProviderMobileHealthClient();
        mhpResourceUri = IntegrationTestConfiguration.getMobileHealthServerBaseUri() + "/mhpuser" ;
        Document mhpUserXml = client.getAsXml(mhpResourceUri);
        patientLinkNode = XpathHelper.getNode(mhpUserXml, "//m:mhpUser/atom:link[@title='patients-operational']");
        schedulingResourceDirectoryLinkNode = XpathHelper.getNode(mhpUserXml, "//m:mhpUser/atom:link[@title='scheduling-resource-directory']");
        deleteTokenURI = TestHelper.getDeleteTokenURI();
    }

    @Test
    public void VerifySchedulingResourceDirectoryUri() {
        assertNotNull(patientLinkNode);
    }

    @AfterClass
    public static void destroy() {
        if(client !=null) {
            client.getJerseyClient().destroy();
            client = null;
        }
    }

    @Test
    public void validatePatientSearchUri() {
        Patients patients = searchForPatient("666000004");
        assertNotNull(patients);
    }

    @Test
    public void verifyPatientWaitListUri(){
        Patients patients = searchForPatient("666000004");
        URI waitListUri = patients.get(0).getLink().getUriByTitle("patient-waitlist");
        WaitListEntries waitListEntries = client.getJerseyClient().resource(waitListUri).get(WaitListEntries.class);
        assertNotNull(waitListEntries);
        assertTrue(waitListEntries.size() > 0);
    }

    public Patients searchForPatient(String searchString){
        String searchUri = patientLinkNode.getAttributes().item(0).getNodeValue() + "?searchstring=" + searchString;
        Patients patients = client.getJerseyClient().resource(searchUri).get(PatientSearchResults.class);
        return  patients;
    }

    @Test
    public void VerifyFetchFacilityWaitListCall(){
        String resourceDirectoryUri = schedulingResourceDirectoryLinkNode.getAttributes().item(0).getNodeValue();
        ResourceDirectory resourceDirectory = client.getJerseyClient().resource(resourceDirectoryUri).get(ResourceDirectory.class);
        URI facilityEWLUri = resourceDirectory.getLink().getUriByTitle("facility-ewl-waitlist");
        URI facilityRecallUri = resourceDirectory.getLink().getUriByTitle("facility-recall-waitlist");
        URI facilityNEARUri = resourceDirectory.getLink().getUriByTitle("facility-near-waitlist");

        WaitListEntries facilityEWLList = client.getJerseyClient().resource(facilityEWLUri).get(WaitListEntries.class);
        assertNotNull(facilityEWLList);
        assertTrue(facilityEWLList.size() > 0);

        WaitListEntries facilityRecallList = client.getJerseyClient().resource(facilityRecallUri).get(WaitListEntries.class);
        assertNotNull(facilityRecallList);
        assertTrue(facilityRecallList.size() > 0);

        WaitListEntries facilityNearList = client.getJerseyClient().resource(facilityNEARUri).get(WaitListEntries.class);
        assertNotNull(facilityNearList);
        assertTrue(facilityNearList.size() > 0);

    }

    @Test
    public void VerifyNearWaitListByPatientUri(){
        Patients patients = searchForPatient("GRAPHINGPATIENT");
        URI waitListUri = patients.get(0).getLink().getUriByTitle("patient-waitlist");
        WaitListEntries waitListEntries = client.getJerseyClient().resource(waitListUri).get(WaitListEntries.class);
        assertNotNull(waitListEntries);
        assertTrue(waitListEntries.size() > 0);
        assertEquals("NEAR", waitListEntries.get(0).getWaitListType());
    }

    @Test
    public void VerifyRecallWaitListByPatientUri(){
        Patients patients = searchForPatient("BCMA,EIGHTEEN-PATIENT");
        URI waitListUri = patients.get(0).getLink().getUriByTitle("patient-waitlist");
        WaitListEntries waitListEntries = client.getJerseyClient().resource(waitListUri).get(WaitListEntries.class);
        assertNotNull(waitListEntries);
        assertTrue(waitListEntries.size() > 0);
        assertEquals("RECALL", waitListEntries.get(0).getWaitListType());
    }

    @Test
    public void fetchPatientBookedAppointment(){
        URI uri = createPatientBookedAppointmentUri("777","237");
        BookedAppointments bookedAppointments = client.getJerseyClient().resource(uri).get(BookedAppointments.class);
        assertNotNull(bookedAppointments);
    }

    @Test
    public void deleteToken(){
        if(client!=null){
            client.getJerseyClient().resource(deleteTokenURI).delete();
        }
    }

    private URI createPatientBookedAppointmentUri(String siteCode, String patientId){
        String uriFromat = String.format("%s/scheduling-service/site/%s/patient/dfn-%s/%s/booked-appointments?startDate=" +startDate,
                IntegrationTestConfiguration.getSchedulingManagerBaseUri(),
                siteCode, siteCode, patientId);
        return UriBuilder.fromUri(uriFromat).build();
    }
}
