Imports System
Imports System.IO
Imports System.Net
Imports System.Web.Services.Protocols
Imports PrintableResultsSampleCode.PrintableResultsWebService

' Class PrintableResultsSample requests lab order (PDF file) from the MedPlus
' Hub platform.
'
' Upon its construction, this class will exercise the functions relating to the
' Printable Results Service, which includes:
'
' 1. Performing a new results search (batch size 5),
'    for all provider accounts the hub user has access to,
'    acknowledging the results, and getting more results.
'
' 2. Getting an array of provider accounts for the hub user.
'    This represents a subset of provider accounts.
'
' 3. Performing a new results search (batch size 5),
'    with a single provider account, 
'    acknowledging the results, and getting more results.
' 
' 4. Performing a date range search (batch size 5), 
'    acknowledging the results, and getting more results.

Public Class PrintableResultsSample
    ' 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/resultsHub/observations/printable"

    Private proxy As PrintableResultsService

    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 String()
            providerAccountsArray = getProviderAccounts()
            Console.WriteLine("Performing new results search...")
            getResults(providerAccountsArray, "", "")
            Console.WriteLine("Done with date range results search.")

            ' 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 date range search...")
            getResults(Nothing, "01/01/2004", "01/01/2009")
            Console.WriteLine("Done with date range results search.")

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

        End Try
    End Sub

    Private Function getWebServiceObject() As PrintableResultsService
        Dim webService As PrintableResultsService

        Try
            '-------------------------------------------------------
            'STEP 1: CREATE WEB SERVICE REFERENCE
            '-------------------------------------------------------
            webService = New PrintableResultsService
        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


    ' 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 String(), ByVal startDate As String, ByVal endDate As String) As ResultsRequest
        Dim uReq As New ResultsRequest

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

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

        '------------------------------------------------------------------
        '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

        Return uReq
    End Function

    Private Sub getResults(ByVal myProviderAccounts As String(), ByVal startDate As String, ByVal endDate As String)
        Dim bInitialRequest As Boolean = True
        Dim bContinue As Boolean = True
        Dim numPDFs As Integer = 0
        Dim requestID As String = ""
        Dim myPrintableResponse As PrintableResultsResponse = Nothing
        Dim printableResultsRequest As ResultsRequest

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

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

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

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

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

            If myPrintableResponse.resultInfo Is Nothing Then
                ' empty array, no HL7 messages returned
                Console.WriteLine("PDF not found.")
                bContinue = False
            Else
                numPDFs = numPDFs + 1
                Console.WriteLine("PDF found: " + myPrintableResponse.fileName)

                writeResultDataToFile(myPrintableResponse)

                ' Acknowledge result
                Console.WriteLine("Acknowledging PDF file...")
                proxy.acknowledgeResults(requestID, myPrintableResponse.resultInfo, "")

                bContinue = CBool(myPrintableResponse.isMore)
            End If
        End While

        Console.WriteLine("Total PDFs found: " + numPDFs.ToString)
    End Sub

    ' The getProviderAccounts method will call the Hub and get a list
    ' of provider accounts the hub user has access to.  It then places
    ' the first one in a String array and returns the array, which can 
    ' be passed to the getResults method to get results for a subset 
    ' of the provider accounts the hub user has access to.
    Public Function getProviderAccounts() As String()
        Dim asProvAccts(0) As String

        Try
            ' Get Provider Accounts associated with this hub account
            Console.WriteLine("Getting Provider Accounts...")

            Dim myProviderAccounts As ProviderAccount() = proxy.getProviderAccounts()
            Dim myAccount As ProviderAccount

            If Not myProviderAccounts Is Nothing Then
                If myProviderAccounts.Length > 0 Then
                    For Each myAccount In myProviderAccounts
                        Console.WriteLine("ID: " + myAccount.accountId + _
                                          ", Name: " + myAccount.accountName + _
                                          ", Provider: " + myAccount.provider.name)
                    Next

                    asProvAccts(0) = Trim(myProviderAccounts(0).accountId)
                End If
            End If

            getProviderAccounts = asProvAccts

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

        End Try
        Return asProvAccts
    End Function

    ' Example of how to write the PDF out to a file
    Private Sub writeResultDataToFile(ByVal myPrintableResponse As PrintableResultsResponse)
        Try
            ' Open a file with the file name provided in the response object.  
            Dim fs As New FileStream(myPrintableResponse.fileName, FileMode.OpenOrCreate)
            Dim bw As New BinaryWriter(fs)  ' Use a BinaryWriter to copy the Byte array to a file
            bw.Write(myPrintableResponse.resultData)
            bw.Close()
            fs.Close()

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

        End Try
    End Sub

End Class
