Imports System
Imports System.IO
Imports System.Net
Imports System.Web.Services.Protocols
Imports ObservationResultsSampleCode.ObservationResultWebService


Public Class ObservationResultsSample
    ' USERNAME designates the Hub user name used to
    ' authenticate to the Hub web service
    Private Const USERNAME As String = "test"

    ' PASSWORD designates the password associated with
    ' the Hub user when authenticating to the web service
    Private Const PASSWORD As String = "customer1"

    ' WEB_SERVICE_URL designates the end point used to
    ' connect to the Hub's Printbale Results web service
    Private Const WEB_SERVICE_URL As String = "https://cert.hub.care360.com/observation/result/service"

    Private Const MAX_MESSAGES As String = "5"

    Private Const START_DATE As String = "01/01/2004"
    Private Const END_DATE As String = "01/01/2009"

    Private proxy As ObservationResultService

    Public Sub New()
        Try
            proxy = getWebServiceObject()

            ' EXAMPLE 1:
            ' Perform a new results search using all provider accounts.  
            ' This is the most common scenario for developing vendors.
            ' Return max of 5 results.
            Console.WriteLine("Performing new results search...")
            getResults(Nothing, "", "")
            Console.WriteLine("Done with date range results search.")

            ' EXAMPLE 2:
            ' Perform a new results search using just one provider account. 
            ' Return max of 5 results.
            Dim providerAccountsArray() As ProviderAccount
            providerAccountsArray = proxy.getProviderAccounts()

            Dim subset(1) As ProviderAccount
            subset(0) = providerAccountsArray(0)

            Console.WriteLine("Performing new results search, using one provider account...")
            getResults(subset, "", "")
            Console.WriteLine("Done with new results search using one provider account.")

            ' EXAMPLE(3)
            ' Date range search using all provider accounts. Max of 5 results, will 
            ' acknowledge those results and then get more until they're all processed
            Console.WriteLine("Performing limited date range search...")
            getResults(Nothing, START_DATE, END_DATE)
            Console.WriteLine("Done with date range results search.")

        Catch ex As Exception
            Console.WriteLine(ex.Message)

        End Try
    End Sub

    Private Function getWebServiceObject() As ObservationResultService
        Dim webService As ObservationResultService

        Try
            '-------------------------------------------------------
            'STEP 1: CREATE WEB SERVICE REFERENCE
            '-------------------------------------------------------
            webService = New ObservationResultService
        Catch except As Exception
            Console.Write(except.StackTrace)
            webService = Nothing
            Throw except
        End Try

        If Not (webService Is Nothing) Then
            '------------------------------------------------------------------
            'STEP 2: CREATE CREDENTIALS OBJECT CONTAINING USERNAME AND PASSWORD
            '------------------------------------------------------------------
            webService.Credentials = New NetworkCredential(USERNAME, PASSWORD)

            ' By default the client will attempt to call the web service without 
            ' sending the credentials. If the server returns a 401 HTTP response, 
            ' the client makes the call again with the credentials. If we set 
            ' PreAuthenticate to True, the client will include the credentials on 
            ' the initial call and eliminate this extra processing.
            '
            ' This should probably be set in the web service object's constructor,
            ' but has been included here to demonstrate.
            webService.PreAuthenticate = True

            '------------------------------------------------------------------
            'STEP 3: SET WEB SERVICE URL
            '------------------------------------------------------------------
            If WEB_SERVICE_URL.Length > 0 Then
                webService.Url = WEB_SERVICE_URL
            End If
        End If

        getWebServiceObject = webService
    End Function

    Private Sub getResults(ByVal myProviderAccounts As ProviderAccount(), ByVal startDate As String, ByVal endDate As String)
        Dim bInitialRequest As Boolean = True
        Dim bContinue As Boolean = True
        Dim numResults As Integer = 0
        Dim requestID As String = ""
        Dim myObservationResponse As ObservationResultResponse = Nothing
        Dim observationResultRequest As ObservationResultRequest

        While bContinue
            If bInitialRequest Then
                bInitialRequest = False
                Console.WriteLine("Making a first pass...")

                '------------------------------------------------------------------
                'STEP 1: GENERATE RESULTS REQUEST OBJECT
                '------------------------------------------------------------------
                observationResultRequest = buildResultsRequest(myProviderAccounts, startDate, endDate)

                '--------------------------------------------------------------
                'STEP 2: SUBMIT REQUEST TO THE HUB
                '--------------------------------------------------------------
                myObservationResponse = proxy.getResults(observationResultRequest)

                If myObservationResponse Is Nothing Then
                    Console.WriteLine("Failed to properly call getHL7Results WebService method.")
                End If
            Else
                Console.WriteLine("Making another pass...")
                myObservationResponse = proxy.getMoreResults(requestID)

                If myObservationResponse Is Nothing Then
                    Console.WriteLine("Failed to properly call getMoreHL7Results WebService method.")
                End If
            End If

            requestID = myObservationResponse.requestId
            Console.WriteLine("Request ID: " + requestID)

            If myObservationResponse.observationResults Is Nothing Then
                ' empty array, no HL7 messages returned
                Console.WriteLine("# of Messages on Pass: 0")
                bContinue = False
            Else
                numResults = numResults + myObservationResponse.observationResults.Length
                Console.Write("# of Messages on Pass: ")
                Console.WriteLine(myObservationResponse.observationResults.Length)

                ' Acknowledge result(s)
                Dim myAcknowledgment As New Acknowledgment
                myAcknowledgment.requestId = requestID
                myAcknowledgment.acknowledgedResults = generateAckMessages(myObservationResponse)
                proxy.acknowledgeResults(myAcknowledgment)

                bContinue = myObservationResponse.isMore
            End If
        End While

        Console.WriteLine("Total results found: " + numResults.ToString)
    End Sub

    ' The getWebServicePrintableMessage function will take the parameters for a results request and gernerate the object
    ' to pass to the web method
    Private Function buildResultsRequest(ByVal myProviderAccounts As ProviderAccount(), ByVal startDate As String, ByVal endDate As String) As ObservationResultRequest
        Dim uReq As New ObservationResultRequest

        '------------------------------------------------------------------
        'STEP 1: SET PROVIDER ACCOUNTS
        '------------------------------------------------------------------
        If Not myProviderAccounts Is Nothing Then
            uReq.providerAccounts = myProviderAccounts
        End If

        '------------------------------------------------------------------
        'STEP 2: SET MAXIMUM NUMBER OF MESSAGES TO RETRIEVE AT ONCE
        '------------------------------------------------------------------
        uReq.maxMessages = MAX_MESSAGES

        '------------------------------------------------------------------
        'STEP 3: SET DATE RANGE TO GET RESULTS
        '------------------------------------------------------------------
        If (endDate.Length > 0) Then
            uReq.endDate = endDate
        End If

        If (startDate.Length > 0) Then
            uReq.startDate = startDate
        End If

        uReq.retrieveFinalsOnly = False

        buildResultsRequest = uReq
    End Function

    Private Function generateAckMessages(ByVal observationResultResponse As ObservationResultResponse) As AcknowledgedResult()
        Dim results As ObservationResult()

        ' Get the results from the response object.
        results = observationResultResponse.observationResults
        Console.Write("Acknowledging ")
        Console.Write(results.Length)
        Console.WriteLine(" results.")

        Dim ackMessages(results.Length - 1) As AcknowledgedResult

        For i = 0 To results.Length - 1
            ' Process each message and build an Acknowledgment object to
            ' acknowledge the result.
            Console.Write("Message: ")
            Console.WriteLine(i)
            Console.WriteLine("---------")
            Console.WriteLine("The HL7 Message: " + System.Text.Encoding.UTF8.GetString(results(i).HL7Message))
            Console.Write("There are ")
            If Not (results(i).documents Is Nothing) Then
                Console.Write(results(i).documents.Length)
            Else
                Console.Write("0")
            End If

            Console.WriteLine(" attached PDFs.")
            Console.WriteLine()
            Console.WriteLine()

            ' Process the result

            ' Send an Ack/Nack message back for each result received.
            ackMessages(i) = buildAcknowledgment(results(i))

        Next i

        Return ackMessages
    End Function

    Private Function buildAcknowledgment(ByVal result As ObservationResult) As AcknowledgedResult

        Dim acknowledgment As New AcknowledgedResult

        acknowledgment.resultId = result.resultId
        acknowledgment.ackCode = "ACK"

        If Not (result.documents Is Nothing) Then
            Dim docIds(result.documents.Length - 1) As String

            For i = 0 To result.documents.Length - 1
                docIds(i) = result.documents(i).documentId
            Next i

            acknowledgment.documentIds = docIds
        End If

        Return acknowledgment
    End Function

End Class
