using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;



namespace CompendiumServicesSampleCodeCS

{

    using NUnit.Framework;

    using Newtonsoft.Json;

    using Newtonsoft.Json.Serialization;



    using System.Net;

    using System.IO;

    using System.IO.Compression;



    /// <summary>

    /// Class CompendiumServicesSample contains three tests to simulate each step of the process to retrieve Compendium files.

    /// The steps are as follows:

    /// 1. Get List Of Files Available For Download

    /// 2. Download Individual Zip File

    /// 3. Ack Individual Downloaded Zip File

    /// </summary>

    [TestFixture]

    public class CompendiumServicesSample

    {

        private string _listOfCompendiumFilesAvailableResponse;

        /// <summary>

        /// JSON LIST OF COMPENDIUM FILES AVAILABLE Response

        /// </summary>

        public string ListOfCompendiumFilesAvailableResponse

        {

            get { return _listOfCompendiumFilesAvailableResponse; }

            set { _listOfCompendiumFilesAvailableResponse = value; }

        }



        private string _ackResponse;

        /// <summary>

        /// JSON ACK Response

        /// </summary>

        public string AckResponse

        {

            get { return _ackResponse; }

            set { _ackResponse = value; }

        }



        /// <summary>

        /// Gets the list of available compendium files ready for retrieval.

        /// </summary>

        /// <param name="username">rest web service username</param>

        /// <param name="password">rest web service password</param>

        /// <param name="restServiceUri">rest web service uri</param>

        private void GetListOfFilesAvailableForDownload(string username, string password, string restServiceUri)

        {

            try

            {

                System.Console.WriteLine("Building the request to send to the restful service.");

                HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(restServiceUri);

                httpRequest.Method = "GET";

                httpRequest.ContentType = "application/json";

                httpRequest.Timeout = 20000;

                httpRequest.Credentials = new NetworkCredential(username, password);



                System.Console.WriteLine("Executing call against the restful service.");

                HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();



                System.Console.WriteLine("Saving the actual response received from the hub restful service.");

                this.ListOfCompendiumFilesAvailableResponse = new StreamReader(response.GetResponseStream()).ReadToEnd();



                System.Console.WriteLine(this.ListOfCompendiumFilesAvailableResponse);

            }

            catch (WebException e)

            {

                using (var stream = e.Response.GetResponseStream())

                using (var reader = new StreamReader(stream))

                {

                    System.Console.WriteLine(reader.ReadToEnd());

                }



                System.Console.WriteLine("Exception encountered while performing the GetListOfFilesAvailableForDownload action");

                throw;

            }

            catch (Exception)

            {

                System.Console.WriteLine("Exception Encountered while performing the GetListOfFilesAvailableForDownload action");

                throw;

            }



        }



        /// <summary>

        /// Downloads an individual compendium file to a specified location.

        /// </summary>

        /// <param name="username">rest web service username</param>

        /// <param name="password">rest web service password</param>

        /// <param name="restServiceUri">rest web service uri</param>

        /// <param name="saveFilePath">location to save downloaded file</param>

        private void DownloadIndividualZipFile(string username, string password, string restServiceUri, string saveFilePath)

        {

            try

            {

                System.Console.WriteLine("Building the request to send to the restful service.");

                HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(restServiceUri);

                httpRequest.Method = "GET";

                httpRequest.ContentType = "application/json";

                httpRequest.Accept = "application/json";

                httpRequest.Timeout = 200000;

                httpRequest.Credentials = new NetworkCredential(username, password);



                System.Console.WriteLine("Executing call against the restful service.");

                HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();



                System.Console.WriteLine(String.Format("Decompressing the file to the following location: [{0}]", saveFilePath));



                using (FileStream decompressedFileStream = File.Create(saveFilePath))

                {

                    byte[] buffer = new byte[4096];

                    int numRead;

                    while ((numRead = response.GetResponseStream().Read(buffer, 0, buffer.Length)) != 0)

                    {

                        decompressedFileStream.Write(buffer, 0, numRead);

                    }

                }



            }

            catch (WebException e)

            {

                using (var stream = e.Response.GetResponseStream())

                using (var reader = new StreamReader(stream))

                {

                    System.Console.WriteLine(reader.ReadToEnd());

                }



                System.Console.WriteLine("Exception encountered while performing DownloadIndividualZipFile action");

                throw;

            }

            catch (Exception)

            {

                System.Console.WriteLine("Exception encountered while performing DownloadIndividualZipFile action");

                throw;

            }

        }



        /// <summary>

        /// Acks an individual compendium file

        /// </summary>

        /// <param name="username">rest web service username</param>

        /// <param name="password">rest web service psasword</param>

        /// <param name="restServiceUri">rest web service uri</param>

        private void AckIndividualDownloadedZipFile(string username, string password, string restServiceUri)

        {

            try

            {

                System.Console.WriteLine("Building the request to send to the restful service.");

                HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(restServiceUri);

                httpRequest.Method = "GET";

                httpRequest.ContentType = "application/json";

                httpRequest.Timeout = 20000;

                httpRequest.Credentials = new NetworkCredential(username, password);



                System.Console.WriteLine("Executing call against the restful service.");

                HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();



                System.Console.WriteLine("Saving the actual response received from the hub restful service.");

                this.AckResponse = new StreamReader(response.GetResponseStream()).ReadToEnd();



                System.Console.WriteLine(this.AckResponse);

            }

            catch (WebException e)

            {

                using (var stream = e.Response.GetResponseStream())

                using (var reader = new StreamReader(stream))

                {

                    System.Console.WriteLine(reader.ReadToEnd());

                }



                System.Console.WriteLine("Exception encountered while performing AckIndividualDownloadedZipFile action");

                throw;

            }

            catch (Exception)

            {

                System.Console.WriteLine("Exception Encountered while performing the AckIndividualDownloadedZipFile action");

                throw;

            }

        }



        /// <summary>

        /// Sample test username

        /// </summary>

        private const string USERNAME = "CompendiumManagement";



        /// <summary>

        /// Sample test password

        /// </summary>

        private const string PASSWORD = "passw0rd";



        /// <summary>

        /// Sample server location - base for the REST URI

        /// </summary>

        private const string SERVER = "http://hubvelocity.dev.medplus.com";



        /// <summary>

        /// Sample path where to save the downloaded compendium files

        /// </summary>

        private const string SAVE_FILE_PATH = @"C:\Temp\";



        /// <summary>

        /// Test flow for getting, retrieving, and acking compendium files.

        /// </summary>

        [Test]

        public void TestRetrievalOfCompendiumFiles()

        {

            this.GetListOfFilesAvailableForDownload(USERNAME, PASSWORD, SERVER + "/rest/compendiums/v1/requestCompendiums");

            CompendiumRequestResponseDto response = JsonConvert.DeserializeObject<CompendiumRequestResponseDto>(this.ListOfCompendiumFilesAvailableResponse);



            if (response.fullFileLinks != null)

            {

                foreach (CompendiumFileNameDto fullFile in response.fullFileLinks)

                {

                    this.DownloadIndividualZipFile(USERNAME, PASSWORD, SERVER + fullFile.retrieveURI, SAVE_FILE_PATH + fullFile.fileName);

                    this.AckIndividualDownloadedZipFile(USERNAME, PASSWORD, SERVER + fullFile.ackURI);

                }

            }

            else

            {

                System.Console.WriteLine("There are no Full Files Available for this account.");

            }



            if (response.deltaFileLinks != null)

            {

                foreach (CompendiumFileNameDto fullFile in response.deltaFileLinks)

                {

                    this.DownloadIndividualZipFile(USERNAME, PASSWORD, SERVER + fullFile.retrieveURI, SAVE_FILE_PATH + fullFile.fileName);

                    this.AckIndividualDownloadedZipFile(USERNAME, PASSWORD, SERVER + fullFile.ackURI);

                }

            }

            else

            {

                System.Console.WriteLine("There are no Delta Files Available for this account.");

            }



            if (response.previouslyNotifiedDeltasLinks != null)

            {

                foreach (CompendiumFileNameDto fullFile in response.previouslyNotifiedDeltasLinks)

                {

                    this.DownloadIndividualZipFile(USERNAME, PASSWORD, SERVER + fullFile.retrieveURI, SAVE_FILE_PATH + fullFile.fileName);

                    this.AckIndividualDownloadedZipFile(USERNAME, PASSWORD, SERVER + fullFile.ackURI);

                }

            }

            else

            {

                System.Console.WriteLine("There are no Previously Notified Delta Files Available for this account.");

            }



            if (response.previouslyNotifiedFullFileLinks != null)

            {

                foreach (CompendiumFileNameDto fullFile in response.previouslyNotifiedFullFileLinks)

                {

                    this.DownloadIndividualZipFile(USERNAME, PASSWORD, SERVER + fullFile.retrieveURI, SAVE_FILE_PATH + fullFile.fileName);

                    this.AckIndividualDownloadedZipFile(USERNAME, PASSWORD, SERVER + fullFile.ackURI);

                }

            }

            else

            {

                System.Console.WriteLine("There are no Previously Notified Full Files Available for this account.");

            }



            if (response.errorMessage != null)

            {

                System.Console.WriteLine(response.errorMessage);

            }

        }

    }

}

