using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Timers;
using System.Net;
using System.IO;
using PlutoServer.MSL;
using Yaulw.Net;
using Yaulw.Thread;
using Yaulw.Assembly;
using Yaulw.Tools;
using System.Diagnostics;

namespace RegistrationAPI_Tester
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        // Use this internal Channel
        internal const uint INTERNAL_CHANNEL_PORT = 1945;

        // The Mobile Service Name
        internal const string MOBILE_API_SERVICE_NAME = "McKesson MSL Mobile Api Server";

        // The Mobile Service Exe
        internal const string MOBILE_API_SERVICE_EXE = "PlutoServer.MSL.exe";

        // Use this host to check, if we are on the McKesson Network
        internal const string MCK_HOST_TO_CHECK_ON_MCK_NETWORK = "ndh1fs01.mckesson.com";

        // Used to display non-available fields
        internal const string NOT_AVAILABLE = "N/A";

        // Did the service statup on the McKesson Network? Initialized upon Service Start        
        internal static bool IsOnMcKessonNetwork = false;

        // To keep track when we last time started the service
        private DateTime LastTimeServiceWasStarted = DateTime.MinValue;

        // The current Directory the exe is running from
        internal static string curRunningDirectory = "";

        /// <summary>
        /// Retrieve the LocalFileNameNPath for SetupMini File (TEMP FOLDER)
        /// </summary>
        /// <returns></returns>
        private static string MiniSetupFileNameNPath
        {
            get
            {
                string LocalFileNameNPath = Yaulw.Tools.PathNaming.PathEndsWithSlash(Path.GetTempPath()) + "SetupMini.exe";
                return LocalFileNameNPath;
            }
        }

        /// <summary>
        /// Retrieve the LocalFileNameNPath for Setup File (TEMP FOLDER)
        /// </summary>
        /// <returns></returns>
        private static string SetupFileNameNPath
        {
            get
            {
                string LocalFileNameNPath = Yaulw.Tools.PathNaming.PathEndsWithSlash(Path.GetTempPath()) + "Setup.exe";
                return LocalFileNameNPath;
            }
        }

        #region  Dispatcher

        /// <summary>
        /// Dispatcher Timer
        /// </summary>
        private TTimerDisp dispTimer = null;

        /// <summary>
        /// Dispatch Event Handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ElapsedEventHandler(object sender, ElapsedEventArgs e)
        {
            System.Timers.Timer timer = (System.Timers.Timer) sender;
            timer.Enabled = false;
            CheckServiceStatus();
            timer.Enabled = true;
        }

        #endregion

        #region Set Service Status

        /// <summary>
        /// Set the Service Status
        /// </summary>
        /// <param name="strStatus"></param>
        private void SetServiceStatus(string strStatus, System.Drawing.Color color)
        {
            this.lblServiceStatus.Text = strStatus;
            this.lblServiceStatus.ForeColor = color;
        }

        /// <summary>
        /// Set the Service Status
        /// </summary>
        /// <param name="strStatus"></param>
        private void SetServiceStatusGood(string strStatus)
        {
            SetServiceStatus(strStatus, System.Drawing.Color.Green);            
        }

        /// <summary>
        /// Set the Service Status (Bad) Disables all readonly text fields and buttons)
        /// </summary>
        /// <param name="strStatus"></param>
        private void SetServiceStatusBad(string strStatus)
        {
            SetServiceStatus(strStatus, System.Drawing.Color.Red);
            ClearAllReadOnlyTextFields();
            DisableAllButtons();
        }

        /// <summary>
        /// Clear all ReadOnly Text Fields (we are in a bad state)
        /// </summary>
        private void ClearAllReadOnlyTextFields()
        {
            textHostGUID.Text = "";
            textExternalIP.Text = "";
            textInternalIP.Text = "";
            textExternalPort.Text = "";
            lblServiceVersion.Text = "";
            lblLatestVersion.Text = "";
            textDetectedInternalIP.Text = "";
            textDetectedExternalIP.Text = "";
        }

        /// <summary>
        /// Disable all buttons (we are in a bad state)
        /// </summary>
        private void DisableAllButtons()
        {
            btnServiceStartStop.Enabled = false;
            btnUpdateService.Enabled = false;
            btnUpdateHost.Enabled = false;
            btnIsServerReachable.Enabled = false;
        }

        #endregion

        #region Versioning

        /// <summary>
        /// Fetch the Latest Version that is Online
        /// </summary>
        /// <returns>valid version object or null if error occured</returns>
        internal static Version FetchOnlineVerion()
        {
            string fetchVersion = Yaulw.Net.WCHelper.ScreenScrapeFromURL(Configuration.CHECK_VERSION_URL);
            if (!String.IsNullOrEmpty(fetchVersion))
            {
                fetchVersion = fetchVersion.Replace("\n", "");
                fetchVersion = fetchVersion.Replace("\r", "");
                fetchVersion = fetchVersion.Trim();

                try
                {
                    Version version = new Version(fetchVersion);
                    return version;
                }
                catch (Exception) { /* ignore */ }
            }
            return null;
        }

        /// <summary>
        /// Quick Check to see if the Local Service is out of date
        /// </summary>
        /// <returns></returns>
        internal static bool IsLocalServiceVersionOutOfDate(string LocalVersion, string OnlineVersion)
        {
            if (!String.IsNullOrEmpty(LocalVersion) && !String.IsNullOrEmpty(OnlineVersion))
            {
                Version local = new Version(LocalVersion);
                Version online = new Version(OnlineVersion);
                if (online.Major == local.Major && online > local)                    
                    return true;
            }
            return false;
        }

        #endregion

        /// <summary>
        /// Main Status Logic
        /// </summary>
        private void CheckServiceStatus()
        {
            try
            {
                // Disable Reinstall by default, enable only in certain states
                EnableReinstallServiceButton(false);

                bool bHasConnection = Yaulw.Net.IPHostHelper.HasConnection();
                if (!bHasConnection)
                {
                    SetServiceStatusBad("Network Disconnected");                
                    return;
                }

                // Enable the stop button, but only if Last Started has been longer than 2 minutes
                TimeSpan ts = DateTime.Now - LastTimeServiceWasStarted;
                bool bEnableStopButton = (ts.TotalMinutes >= 2.0);

                bool bIsServiceRunning = Yaulw.Process.ServiceW.IsServiceRunning(MOBILE_API_SERVICE_NAME);
                if (!bIsServiceRunning)
                {
                    SetServiceStatusBad("Service not running");
                    btnServiceStartStop.Text = "Start Service";
                    btnServiceStartStop.Enabled = true;

                    // Enable Update button, if we can access fileVersion of Pluto Service           
                    if (File.Exists(curRunningDirectory + MOBILE_API_SERVICE_EXE))
                    {
                        FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(curRunningDirectory + MOBILE_API_SERVICE_EXE);
                        if (fvi != null)
                        {
                            lblServiceVersion.Text = fvi.FileVersion;
                            EnableButtonIfServiceIsOutOfDate();
                        }

                        // Enable Reinstall
                        EnableReinstallServiceButton(true);
                    }                    
                    return;
                }

                bool bCanConnectViaPort = Yaulw.Net.IPHostHelper.IsPortOpen(IPAddress.Loopback, (int) INTERNAL_CHANNEL_PORT);
                if (!bCanConnectViaPort)
                {
                    SetServiceStatusBad("DiagnoseMobile can't open the port to the Service");

                    // Service is running so enable the stop button
                    btnServiceStartStop.Text = "Stop Service";
                    btnServiceStartStop.Enabled = bEnableStopButton;
                    return;
                }

                // Service is running so enable the stop button
                btnServiceStartStop.Text = "Stop Service";                
                btnServiceStartStop.Enabled = bEnableStopButton;                

                // Now let's start gathering Pluto Data
                textHostGUID.Text = Pluto.MSL.Api.API.GetHostGUID();
                
                // if we got here, then the above call didn't throw an exception,
                // so we are doing good
                SetServiceStatusGood("Running");
                textInternalIP.Text = Pluto.MSL.Api.API.GetLocalIP();
                
                // External IP could not be set, so don't confuse the customer,
                // use N/A instead of the default values
                IPAddress externalIP = IPAddress.None;
                if(IPAddress.TryParse(Pluto.MSL.Api.API.GetExternalIP(), out externalIP))
                {
                    if (IsOnMcKessonNetwork || externalIP == IPAddress.None)
                        textExternalIP.Text = NOT_AVAILABLE;
                    else
                        textExternalIP.Text = externalIP.ToString();
                }

                // External Port could not be set, so don't confuse the customer,
                // use N/A instead of the default values
                int nPort = Pluto.MSL.Api.API.GetExternalPort();
                if(nPort == -1)
                   textExternalPort.Text = NOT_AVAILABLE;  
                else
                   textExternalPort.Text = nPort.ToString();  

                // Check the Versions
                lblServiceVersion.Text = Pluto.MSL.Api.API.GetAPIVersion();
                EnableButtonIfServiceIsOutOfDate();

                // Detect thee IP stuff 
                textDetectedInternalIP.Text = Yaulw.Net.IPHostHelper.GetFirstLocalIPAddress().ToString();                
                externalIP = Yaulw.Net.IPHostHelper.GetExternalIP();
                if (IsOnMcKessonNetwork || externalIP == IPAddress.None)
                    textDetectedExternalIP.Text = NOT_AVAILABLE;
                else
                    textDetectedExternalIP.Text = externalIP.ToString();

                // Enable buttons
                btnUpdateHost.Enabled = true;
                btnIsServerReachable.Enabled = true;

                // Enable Reinstall
                EnableReinstallServiceButton(true);
            }
            catch (Exception e)
            {
                SetServiceStatusBad(e.Message);                
            }
        }

        /// <summary>
        /// Responsible for fetching the online version and enabling the Update Button if 
        /// service is out of date. The lblServiceVersion.Text needs to be set prior to calling
        /// this function. Will be used to compare.
        /// </summary>
        private void EnableButtonIfServiceIsOutOfDate()
        {
            if (!String.IsNullOrEmpty(lblServiceVersion.Text))
            {
                Version OnlineVersion = FetchOnlineVerion();
                if(OnlineVersion != null)
                {
                    lblLatestVersion.Text = OnlineVersion.ToString();
                    bool bIsOutOfDate = IsLocalServiceVersionOutOfDate(lblServiceVersion.Text, lblLatestVersion.Text);
                    btnUpdateService.Enabled = bIsOutOfDate;
                    lblUpdate.Visible = bIsOutOfDate;
                }
            }
        }

        /// <summary>
        /// Responsible for enabling the reinstall Service Button (should only
        /// be enabled in certain states)
        /// </summary>
        /// <param name="bEnable"></param>
        private void EnableReinstallServiceButton(bool bEnable)
        {
            lblReinstall.Visible = bEnable;
            btnReinstall.Enabled = bEnable;
        }

        /// <summary>
        /// Main Form OnLoad()
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_Load(object sender, EventArgs e)
        {
            try
            {
                // Load the PlutoServer.MSL.config File * Helps us to better test *
                Configuration.Load(false);

                // IMP! Set the Determine External IP Address URL
                Yaulw.Net.IPHostHelper.WHAT_IS_MY_IP_AUTOMATION_URL = Configuration.DETERMINE_EXTERNAL_IP_ADDRESS_URL;

                // Set the Current Run-time directory
                curRunningDirectory = PathNaming.PathEndsWithSlash(Path.GetDirectoryName(AssemblyW.SpecializedAssemblyInfo.GetAssemblyFileNameNPath(AssemblyW.AssemblyST.Entry)));                

                // Are we on the McKesson Network?
                IsOnMcKessonNetwork = Yaulw.Net.IPHostHelper.CanResolveHost(MCK_HOST_TO_CHECK_ON_MCK_NETWORK, true);
                //IsOnMcKessonNetwork = false; // For Debugging
                lblIsOnMckessonNetwork.Visible = IsOnMcKessonNetwork;

                // Set the Pluto API            
                Pluto.MSL.Api.API.SetNetworkSettings(IPAddress.Loopback.ToString(), INTERNAL_CHANNEL_PORT);

                // Set the Registration API
                RegistrationAPI.API.SetNetworkSettings(Configuration.REGISTRATION_HOST_URL, (uint)Configuration.REGISTRATION_CHANNEL_PORT);

                // By Default check the status
                CheckServiceStatus();

                // then start the Status Dispatcher, every 15 seconds
                dispTimer = new TTimerDisp(ElapsedEventHandler, (int)TimeSpan.FromSeconds(15).TotalMilliseconds, true);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Close();
            }
        }

        /// <summary>
        /// Check if the IP is a valid IP and also check that the Port is valid
        /// </summary>
        /// <param name="IP">IP Address as a string</param>
        /// <param name="Port">Port as a string</param>
        /// <returns>true, if IP and Port is valid</returns>
        private bool ValidIPandPort(string IP, string Port)
        {
            if (!String.IsNullOrEmpty(IP) && !String.IsNullOrEmpty(Port))
            {
                IPAddress ip = IPAddress.Any;
                uint nPort = 0;
                bool bValidConfig = IPAddress.TryParse(IP, out ip) && uint.TryParse(Port, out nPort) &&
                                    (nPort > 0) && IPHostHelper.IsValidIPv4Address(ip, false);
                return bValidConfig;
            }
            return false;
        }

        /// <summary>
        /// Update The Service if Needed (auto-closes the app)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnUpdateService_Click(object sender, EventArgs e)
        {
            try
            {

                // Important Sanity Clean-up, this way we know that the service or DiagnoseMobile
                // always downloads the latest setup and runs the latest setup
                try
                {
                    if (File.Exists(MiniSetupFileNameNPath))
                        File.Delete(MiniSetupFileNameNPath);
                }
                catch (Exception)
                {
                    Yaulw.WinForms.MsgBox.ShowError(this, "Updating the Service failed", String.Format("Failed to delete temporary setup file '{0}'. Please delete the file Manually.", MiniSetupFileNameNPath), MessageBoxButtons.OK);
                    return;
                }                

                if (Yaulw.Net.WCHelper.DownloadFileFromURL(Configuration.DOWNLOAD_MINISETUP_URL, MiniSetupFileNameNPath, true))
                {
                    // * Important * sanity check. Kumar/Jeff found this. State can happen that we can reach the
                    // version url but don't actually download the file which then causes the service to crash when
                    // calling PSetupSpwan (might as well also make sure that the new file is equal to the file we expect)                    
                    if (File.Exists(MiniSetupFileNameNPath))
                    {
                        // Stop the service if it exists
                        Yaulw.Installer.Common.StopService(MOBILE_API_SERVICE_NAME, 30);

                        // The auto-update is also forcing a close (however we will also try to committ suicide) 
                        Yaulw.Installer.Common.PSetupSpwan(MiniSetupFileNameNPath, "", false);

                        // * Double Knock-out * Force the Service to close here a kill itself here as well, don't know if this even get's called
                        // but might as well make sure and double punch
                        dispTimer.Stop();
                        Application.Exit();
                    }
                }
            }
            catch (Exception) { /* ignore */}
            Yaulw.WinForms.MsgBox.ShowError(this, "Updating the Service failed", String.Format("Failed to download the file to update the service, please download and install manually: '{0}'", Configuration.DOWNLOAD_MINISETUP_URL), MessageBoxButtons.OK);            
        }

        /// <summary>
        /// Update the IPs
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnUpdateHost_Click(object sender, EventArgs e)
        {
            try
            {
                // Always make sure that the HOST_GUID Exists online on the Gateway Server
                // ~otherwise the update server will always fails and we don't know why, this way the user now knows
                bool bHostExists = RegistrationAPI.API.DoesServerHostGUIDExist(new Guid(textHostGUID.Text));
                if (!bHostExists)
                {
                    Yaulw.WinForms.MsgBox.ShowInfo(this, "No Practices associated with the Server Host Guid", "No Practices have been associated with the McKesson Mobile Gateway. Use Help->Mobile About to retrieve an Api Key and Api Code for a practice to register a practice with the McKesson Mobile Gateway", MessageBoxButtons.OK);
                    return;
                }

                if (IsOnMcKessonNetwork)
                {
                    bool bIsValidInternalConfig = ValidIPandPort(textDetectedInternalIP.Text, INTERNAL_CHANNEL_PORT.ToString());
                    if (bIsValidInternalConfig)
                    {
                        if (RegistrationAPI.API.UpdateServer(new Guid(textHostGUID.Text), textDetectedInternalIP.Text, String.Empty, (uint)INTERNAL_CHANNEL_PORT))
                            Yaulw.WinForms.MsgBox.ShowInfo(this, "Update IP Successful", "Updating the local IP succeeded with the McKesson Mobile Gateway. You are located on the McKesson Network.", MessageBoxButtons.OK);
                        else
                            Yaulw.WinForms.MsgBox.ShowError(this, "Update IP Failed", "Updating the local IP failed with the McKesson Mobile Gateway. You are located on the McKesson Network.", MessageBoxButtons.OK);
                    }
                    else
                    {
                        Yaulw.WinForms.MsgBox.ShowError(this, "Internal IP or Port not valid", String.Format("The internal IP or the Port are invalid internal IP:{0} on Port:{1}", textDetectedInternalIP.Text, INTERNAL_CHANNEL_PORT.ToString()), MessageBoxButtons.OK);
                    }
                }
                else
                {
                    // Check to make sure external IP and Port are valid
                    bool bIsValidExternalConfig = ValidIPandPort(textDetectedExternalIP.Text, textExternalPort.Text);
                    bool bIsValidInternalConfig = ValidIPandPort(textDetectedInternalIP.Text, INTERNAL_CHANNEL_PORT.ToString());
                    if (bIsValidExternalConfig && bIsValidInternalConfig)
                    {
                        if (RegistrationAPI.API.UpdateServer(new Guid(textHostGUID.Text), textDetectedInternalIP.Text, textDetectedExternalIP.Text, uint.Parse(textExternalPort.Text)))
                            Yaulw.WinForms.MsgBox.ShowInfo(this, "Update IPs Successful", "Updating the local IP and external IP succeeded with the McKesson Mobile Gateway.", MessageBoxButtons.OK);
                        else
                            Yaulw.WinForms.MsgBox.ShowError(this, "Update IPs Failed", "Updating the local IP and external IP failed with the McKesson Mobile Gateway.", MessageBoxButtons.OK);
                    }
                    else if (bIsValidInternalConfig)
                    {
                        if (RegistrationAPI.API.UpdateServer(new Guid(textHostGUID.Text), textDetectedInternalIP.Text, String.Empty, (uint)INTERNAL_CHANNEL_PORT))
                            Yaulw.WinForms.MsgBox.ShowInfo(this, "Update IP Successful", "Updating the local IP succeeded with the McKesson Mobile Gateway.", MessageBoxButtons.OK);
                        else
                            Yaulw.WinForms.MsgBox.ShowError(this, "Update IP Failed", "Updating the local IP failed with the McKesson Mobile Gateway.", MessageBoxButtons.OK);
                    }
                    else
                    {
                        Yaulw.WinForms.MsgBox.ShowError(this, "External IP/Internal IP/ or Port not valid", String.Format("The external IP / internal IP or the Port are invalid external IP:{0} internal IP:{1} on Port:{2}", textExternalIP.Text, textDetectedInternalIP.Text, textExternalPort.Text), MessageBoxButtons.OK);
                    }
                }               
            }
            catch (Exception ex)
            {
                Yaulw.WinForms.MsgBox.ShowError(this, "Update IP Exception Thrown", ex.Message, MessageBoxButtons.OK);
            }
        }

        /// <summary>
        /// Is this Server reachable?
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnIsServerReachable_Click(object sender, EventArgs e)
        {
            try
            {                
                if (IsOnMcKessonNetwork)
                {                    
                   Yaulw.WinForms.MsgBox.ShowInfo(this, "McKesson Network", "Server won't be accessible from the Internet. You are located on the McKesson Network.", MessageBoxButtons.OK);                 
                }
                else
                {                                        
                    bool bValidConfig = ValidIPandPort(textDetectedExternalIP.Text, textExternalPort.Text);
                    if (bValidConfig)
                    {
                        if (RegistrationAPI.API.IsServerReachable(textExternalIP.Text, uint.Parse(textExternalPort.Text)))
                            Yaulw.WinForms.MsgBox.ShowInfo(this, "Communication Success", String.Format("McKesson's Mobile Gateway successfully communicated with IP:{0} on Port:{1}", textExternalIP.Text, textExternalPort.Text), MessageBoxButtons.OK);
                        else
                            Yaulw.WinForms.MsgBox.ShowError(this, "Communication Failed", String.Format("McKesson's Mobile Gateway was unsuccessful in communicating with IP:{0} on Port:{1}", textExternalIP.Text, textExternalPort.Text), MessageBoxButtons.OK);
                    }
                    else
                    {
                        Yaulw.WinForms.MsgBox.ShowError(this, "External IP or Port not valid", String.Format("The external IP or the external Port are invalid IP:{0} on Port:{1}", textExternalIP.Text, textExternalPort.Text), MessageBoxButtons.OK);
                    }
                }
            }
            catch (Exception ex)
            {
                Yaulw.WinForms.MsgBox.ShowError(this, "ServerReachable Exception Thrown", ex.Message, MessageBoxButtons.OK);
            }
        }

        /// <summary>
        /// Allows the User to Start/Stop the Service (easily without having to go to SCM to do it)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnServiceStartStop_Click(object sender, EventArgs e)
        {
            bool bStart = btnServiceStartStop.Text.StartsWith("Start");
            if (bStart)
            {
                LastTimeServiceWasStarted = DateTime.Now;
                bool bSuccess = Yaulw.Process.ServiceW.StartService(MOBILE_API_SERVICE_NAME);
                if (bSuccess)
                    Yaulw.WinForms.MsgBox.ShowInfo(this, MOBILE_API_SERVICE_NAME, "The service successfully started.", MessageBoxButtons.OK);
                else
                    Yaulw.WinForms.MsgBox.ShowError(this, MOBILE_API_SERVICE_NAME, "The service start was unsuccessful.", MessageBoxButtons.OK);
            }
            else
            {
                bool bSuccess = Yaulw.Process.ServiceW.StopService(MOBILE_API_SERVICE_NAME);
                if(bSuccess)
                    Yaulw.WinForms.MsgBox.ShowInfo(this, MOBILE_API_SERVICE_NAME, "The service successfully stopped.", MessageBoxButtons.OK);
                else
                    Yaulw.WinForms.MsgBox.ShowError(this, MOBILE_API_SERVICE_NAME, "The service stop was unsuccessful.", MessageBoxButtons.OK);
            }

            // Refresh the form right aways, since the service start/stop occured may as well,
            // otherwise it looks a little clumsy
            CheckServiceStatus();
        }

        /// <summary>
        /// Force a Re-install of the service on this machine (Trouble shooting step)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnReinstall_Click(object sender, EventArgs e)
        {
            try
            {
                DialogResult result = Yaulw.WinForms.MsgBox.ShowInfo(this, "Do you want to continue?", String.Format("You are about to delete the '{0}' and download the complete setup.exe online from:'{1}' and then re-install it. The download may take some time, depending on the speed of your internet connection.", MOBILE_API_SERVICE_NAME, Configuration.DOWNLOAD_SETUP_URL), MessageBoxButtons.YesNo);
                if (result != System.Windows.Forms.DialogResult.Yes)
                    return;

                // Important Sanity Clean-up, this way we know that the service or DiagnoseMobile
                // always downloads the latest setup and runs the latest setup
                try
                {
                    if (File.Exists(SetupFileNameNPath))
                        File.Delete(SetupFileNameNPath);
                }
                catch(Exception) 
                {
                    Yaulw.WinForms.MsgBox.ShowError(this, "Reinstalling the Service failed", String.Format("Failed to delete temporary setup file '{0}'. Please delete the file Manually.", SetupFileNameNPath), MessageBoxButtons.OK);
                    return;
                }

                if (Yaulw.Net.WCHelper.DownloadFileFromURL(Configuration.DOWNLOAD_SETUP_URL, SetupFileNameNPath, true))
                {
                    // * Important * sanity check. Kumar/Jeff found this. State can happen that we can reach the
                    // version url but don't actually download the file which then causes the service to crash when
                    // calling PSetupSpwan (might as well also make sure that the new file is equal to the file we expect)                    
                    if (File.Exists(SetupFileNameNPath))
                    {
                        // Stop the service if it exists
                        Yaulw.Installer.Common.StopService(MOBILE_API_SERVICE_NAME, 30);

                        // The auto-update is also forcing a close (however we will also try to committ suicide) 
                        Yaulw.Installer.Common.PSetupSpwan(SetupFileNameNPath, "", false);

                        // * Double Knock-out * Force the Service to close here a kill itself here as well, don't know if this even get's called
                        // but might as well make sure and double punch
                        dispTimer.Stop();
                        Application.Exit();
                    }
                }
            }
            catch (Exception) { /* ignore */}
            Yaulw.WinForms.MsgBox.ShowError(this, "Reinstalling the Service failed", String.Format("Failed to download the file to update the service, please download and install manually: '{0}'", Configuration.DOWNLOAD_SETUP_URL), MessageBoxButtons.OK);
        }

    }

}
