using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using OrderSubmissionSampleCodeCS.OrderSubmissionWebService;
using System.Web.Services.Protocols;

namespace OrderSubmissionSampleCodeCS
{
    /// <summary>
    /// Class OrderSubmissionSample submits lab order (HL7 messages) to the MedPlus
    /// Hub platform.
    ///
    /// Upon its construction, this class will send an order to the OrderSubmissionService.
    /// </summary>
    class OrderSubmissionSample
    {
        // USERNAME designates the Hub user name used to
        // authenticate to the Hub web service
        private const string USERNAME = "test";

        // PASSWORD designates the password associated with
        // the Hub user when authenticating to the web service
        private const string PASSWORD = "customer1";   // default password

        // WEB_SERVICE_URL designates the end point used to
        // connect to the Hub's Orders web service
        private const string WEB_SERVICE_URL = "https://cert.hub.care360.com/orders/submission/service";

        // SENDING_APPLICATION designates the application that 
        // is sending the order message to Hub
        private const string SENDING_APPLICATION = "HUBWS";

        // SENDING_FACILITY designates the account number provided to you 
        // by Quest for the businessunit you are ordering tests with
        private const string SENDING_FACILITY = "2135800";

        // RECEIVING_FACILITY designates the business unit 
        // within Quest from which the labs are being ordered
        private const string RECEIVING_FACILITY = "THO";

        /// <summary>
        /// The HL7 Order message template
        /// The following "template" is used in constucting the Order.
        /// Replacement fields are:
        /// 0 = sending application (field 3)
        /// 1 = sending facility (field 4) represents the account with Quest Diagnostics
        /// 2 = receiving facility (field 6) The Quest Business Unit for above account
        /// 3 = date time (field 7)
        /// 4 = message control id (field 10) Unique Number identifying this order message
        /// </summary>
        private string ORDER_MESSAGE = "MSH|^~\\&|{0}|{1}||{2}|{3:yyyyMMddHHmm}||ORM^O01|{4}|P|2.3\r" +
                                       "PID|1|11111|||TEST^WIFE||19451212|M|||||3102222222||||||123456789|\r" +
                                       "IN1|1||AUHSC|AETNA|123 ANYSTREET^2^CHICAGO^IL^60305|||A12345||||||||TEST^HUSBAND^|2||123 ANYSTREET^^CHICAGO^IL^60305|||||||||||||||||P123456R|||||||||||T|\r" +
                                       "GT1|1||TEST^HUSBAND^||123 ANYSTREET^^CHICAGO^IL^60305|3102222222||19451212|M|\r" +
                                       "ORC|NW|{4}||||||||||OTH030^MICHIGAN^JOHN^^^^^UPIN|\r" +
                                       "OBR|1|{4}||^^^6399^CBC|||20051223094800|||||||||OTH030^MICHIGAN^JOHN^^^^^UPIN|||||||||||1^^^^^R|\r" +
                                       "DG1|1|ICD|0039|SALMONELLA INFECTION NOS|\r";

        public OrderSubmissionSample()
        {
            try
            {
                // calling sendOrder sends the order to the hub
                Console.WriteLine("Calling sendOrder...");
                sendOrder();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }


        public void sendOrder()
        {
            OrderSubmissionService webService = null;

            try
            {
                //-------------------------------------------------------
                //STEP 1: CREATE WEB SERVICE REFERENCE
                //-------------------------------------------------------
                webService = new OrderSubmissionService();
            }
            catch (Exception ex)
            {
                Console.Write(ex.StackTrace);
                webService = null;
            }

            if (!(webService == null))
            {
                orderResponse response = null;
                orderRequest order = null;

                try
                {
                    //------------------------------------------------------------------
                    //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)
                    {
                        webService.Url = WEB_SERVICE_URL;
                    }

                    //------------------------------------------------------------------
                    //STEP 4: GENERATE ORDER OBJECT
                    //------------------------------------------------------------------
                    order = getWebServiceOrder();

                    //--------------------------------------------------------------
                    //STEP 5: SUBMIT ORDER TO THE HUB
                    //--------------------------------------------------------------

                    response = webService.submitOrder(order);
                }
                catch (SoapException soapEx)
                {
                    string exceptionMessage = soapEx.Detail.InnerText.Replace("" +
                        (char)10 + "", "" + (char)13 + "" +
                        (char)10 + "");

                    Console.Write(exceptionMessage);
                }

                if (!(response == null))
                {
                    //------------------------------------------------
                    //STEP 7: EXAMINE RESPONSE FROM THE HUB
                    //------------------------------------------------
                    Console.WriteLine("Status: <{0}>.", response.status);
                    Console.WriteLine("Transaction Id: <{0}>.", response.orderTransactionUid);
                    Console.WriteLine("Message Control Id: <{0}>.", response.messageControlId);
                    Console.WriteLine("Response Message: <{0}>.", response.responseMsg);

                    if (!(response.validationErrors == null))
                    {
                        foreach (string valErr in response.validationErrors)
                        {
                            Console.WriteLine("Validation Error: <{0}>.", valErr);
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Failed to properly call submitOrder WebService method.");
                }
            }
        }

        /// <summary>
        /// the getWebServiceOrder function creates a proper Order object that will be submitted
        /// to the Hub
        /// </summary>
        /// <param name="webService"></param>
        private orderRequest getWebServiceOrder()
        {
            orderRequest retval = new orderRequest();

            // Create Order Mesage by passing in facility information
            String orderMessage = buildOrderMessage(SENDING_APPLICATION, SENDING_FACILITY, RECEIVING_FACILITY);

            // Convert String to a Byte array and return in an Order object
            retval.hl7Order = System.Text.Encoding.ASCII.GetBytes(orderMessage);
            return retval;
        }

        /// <summary>
        /// the buildOrderMessage function replaces values in the ORDER_MESSAGE template to
        /// create a valid HL7 Order message
        /// </summary>
        /// <param name="sendingApplication"></param>
        /// <param name="sendingFacility"></param>
        /// <param name="receivingFacility"></param>
        /// <returns></returns>
        private String buildOrderMessage(
            String sendingApplication,
            String sendingFacility,
            String receivingFacility)
        {
            //'now' is used for 2 purposes here
            //1 to specify the time that the message was created
            //2 to create a unique message control ID and order number
            System.DateTime now = System.DateTime.Now;
            // parameters for replacement in the template
            Object[] msgParams = new Object[7];
            msgParams[0] = sendingApplication;
            msgParams[1] = sendingFacility;
            msgParams[2] = receivingFacility;
            msgParams[3] = now;
            msgParams[4] = now.Ticks;
            return string.Format(ORDER_MESSAGE, msgParams);
        }

    }

}
