using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Management;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using CommonLib.Misc;
using CommonLib.Windows.Misc;

namespace All_Purpose_Auto_Setup
{
   class NetworkAdapterManager
   {
      // An event that can be raised, allowing other classes to
      // subscribe to it and do what they like with the message.
      public event Action<string, string, List<CommonLib.Windows.Forms.TextFormat.TextFontAndColor>> UpdateStatusDisplayAndLogEvent;

      // this dictionary stores the application to be executed and the arguments associated with it
      // it would look like this:
      // [ c:\app1.exe ]  ->  [path arg arg_path]
      // [ c:\app2.exe ]  ->  [path arg arg_path]
      public Dictionary<ConfigFileManager.Ini_KeyValue<string>, List<ConfigFileManager.Ini_KeyValue<string>>> networkAdapterPciLocationToVarious = new Dictionary<ConfigFileManager.Ini_KeyValue<string>, List<ConfigFileManager.Ini_KeyValue<string>>>();

      // event for thread to notify other threads that it has exited
      private AutoResetEvent _resetEvent = new AutoResetEvent(false);

      Form m_parentForm;

      public NetworkAdapterManager(Form parentForm)
      {
         m_parentForm = parentForm;
      }

      public bool configureNetworkAdapters(string sectionName)
      {
         bool setupSuccessful = true;
         string msg = "", msg2 = "", indentation = String.Empty, errMsg = "";

         CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
         CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
         List<CommonLib.Windows.Forms.TextFormat.TextFontAndColor> textPropList = new List<CommonLib.Windows.Forms.TextFormat.TextFontAndColor>();
         List<CommonLib.Windows.Forms.TextFormat.TextFontAndColor> textPropList2 = new List<CommonLib.Windows.Forms.TextFormat.TextFontAndColor>();

         // set font to default text and color
         textProp.textFont = defaultTextProp.textFont;
         textProp.textColor = Common.getSetupStepTitleColor();
         textProp.wordIndex = 0;
         textProp.wordCount = 100;
         textPropList.Add(textProp);

         DateTime dat1 = DateTime.Now;
         msg = "\n\n<-------------------Date and Time: " + dat1.ToString(@"MM/dd/yyyy     hh:mm:ss tt", System.Globalization.CultureInfo.InvariantCulture) + "------------------->";
         UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

         // set font to default text and color
         textProp.textFont = defaultTextProp.textFont;
         textProp.textColor = Common.getSetupStepTitleColor();
         textProp.wordIndex = 0;
         textProp.wordCount = 10;
         // set font size
         textProp.textFont = new Font(textProp.textFont.Name, 12);
         // set font style
         textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
         textPropList.Add(textProp);

         msg = "\n-=Configuring Network Adapters=-";
         UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

         networkAdapterPciLocationToVarious.Clear();

         ConfigFileManager.readOneToManyDictionary(ConfigFileManager.ms_configGeneralInfo.iniFile,
                    sectionName, @"(nic\d+)_pci_location$", @"(nic\d+)_.+$", networkAdapterPciLocationToVarious);

         setupSuccessful = verifyConfigInfo();

         if (setupSuccessful)
         {
            if (networkAdapterPciLocationToVarious.Count == 0 ||
               (networkAdapterPciLocationToVarious.Count == 1 && networkAdapterPciLocationToVarious.First().Value.Count == 0))
            {
               // set font to default text and color
               textProp.textFont = defaultTextProp.textFont;
               textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SYSTEM_SKIP);
               textProp.wordIndex = 0;
               textProp.wordCount = 2;
               // set font style
               textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
               textPropList.Add(textProp);

               indentation = Common.getIndentation(1);
               msg = "\n" + indentation + "- SKIPPED. Nothing to configure";
               UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
            }

            // for every app to be run
            foreach (KeyValuePair<ConfigFileManager.Ini_KeyValue<string>, List<ConfigFileManager.Ini_KeyValue<string>>> entry in networkAdapterPciLocationToVarious)
            {
               string pciLocation = entry.Key.iniValue;
               string networkAdapterName = "";
               string networkAdapterIp = "";
               string networkAdapterSubnetMask = "";
               string networkAdapterDefaultGateway = "";
               string networkAdapterLinkSpeed = "";
               bool enableDhcp = false;
               List<string> dnsServers = new List<string>();

               getNicInfo(entry.Value, ref networkAdapterName, ref networkAdapterIp,
                           ref networkAdapterSubnetMask, ref networkAdapterDefaultGateway,
                           ref networkAdapterLinkSpeed, ref enableDhcp, ref dnsServers);

               ManagementObject networkAdapter = null;
               ManagementObject networkAdapterConfiguration = null;

               setupSuccessful = NetworkManagement.GetNetworkAdapterAndConfigurationBasedOnPciLocation(ref networkAdapter, ref networkAdapterConfiguration, pciLocation, ref errMsg);

               if (!setupSuccessful)
               {
                  // set font to default text and color
                  textProp.textFont = defaultTextProp.textFont;
                  textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
                  textProp.wordIndex = 0;
                  textProp.wordCount = 2;
                  // set font style
                  textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                  textPropList.Add(textProp);

                  indentation = Common.getIndentation(1);
                  msg = "\n" + indentation + "- FAILED. No network card is associated with PCI Location: " + pciLocation;
                  UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
               }

               if (setupSuccessful && networkAdapterLinkSpeed.Length > 0)
               {
                  setupSuccessful = NetworkManagement.SetNetworkAdapterLinkSpeed(networkAdapter, networkAdapterConfiguration, networkAdapterLinkSpeed, ref errMsg);

                  indentation = Common.getIndentation(1);
                  msg = "\n" + indentation + "Setting link speed to " + networkAdapterLinkSpeed + " for network adapter at PCI Location " + pciLocation;

                  if (setupSuccessful)
                  {
                     // set font to default text and color
                     textProp.textFont = defaultTextProp.textFont;
                     textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
                     textProp.wordIndex = 0;
                     textProp.wordCount = 2;
                     // set font style
                     textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                     textPropList2.Add(textProp);

                     msg2 = " - SUCCESS";
                  }
                  else
                  {
                     // set font to default text and color
                     textProp.textFont = defaultTextProp.textFont;
                     textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
                     textProp.wordIndex = 0;
                     textProp.wordCount = 2;
                     // set font style
                     textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                     textPropList2.Add(textProp);

                     msg2 = " - FAILED. " + errMsg;
                  }

                  UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
                  UpdateStatusDisplayAndLogEvent(msg2, msg2, textPropList2);
               }

               if (setupSuccessful && networkAdapterName.Length > 0)
               {
                  setupSuccessful = NetworkManagement.ChangeNetworkAdapterName(networkAdapter, networkAdapterConfiguration, networkAdapterName, ref errMsg);

                  indentation = Common.getIndentation(1);
                  msg = "\n" + indentation + "Setting adapter name to " + networkAdapterName + " for network adapter at PCI Location " + pciLocation;

                  if (setupSuccessful)
                  {
                     // set font to default text and color
                     textProp.textFont = defaultTextProp.textFont;
                     textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
                     textProp.wordIndex = 0;
                     textProp.wordCount = 2;
                     // set font style
                     textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                     textPropList2.Add(textProp);

                     msg2 = " - SUCCESS";
                  }
                  else
                  {
                     // set font to default text and color
                     textProp.textFont = defaultTextProp.textFont;
                     textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
                     textProp.wordIndex = 0;
                     textProp.wordCount = 2;
                     // set font style
                     textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                     textPropList2.Add(textProp);

                     msg2 = " - FAILED. " + errMsg;
                  }

                  UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
                  UpdateStatusDisplayAndLogEvent(msg2, msg2, textPropList2);
               }

               if (setupSuccessful)
               {
                  if (enableDhcp)
                  {
                     setupSuccessful = NetworkManagement.SetNetworkAdapterForDhcp(networkAdapter, networkAdapterConfiguration, ref errMsg);

                     indentation = Common.getIndentation(1);
                     msg = "\n" + indentation + "Enabling DHCP for network adapter at PCI Location " + pciLocation;

                     if (setupSuccessful)
                     {
                        // set font to default text and color
                        textProp.textFont = defaultTextProp.textFont;
                        textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
                        textProp.wordIndex = 0;
                        textProp.wordCount = 2;
                        // set font style
                        textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                        textPropList2.Add(textProp);

                        msg2 = " - SUCCESS";
                     }
                     else
                     {
                        // set font to default text and color
                        textProp.textFont = defaultTextProp.textFont;
                        textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
                        textProp.wordIndex = 0;
                        textProp.wordCount = 2;
                        // set font style
                        textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                        textPropList2.Add(textProp);

                        msg2 = " - FAILED. " + errMsg;
                     }

                     UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
                     UpdateStatusDisplayAndLogEvent(msg2, msg2, textPropList2);
                  }
                  else
                  {
                     if (setupSuccessful && networkAdapterIp.Length > 0 && networkAdapterSubnetMask.Length > 0)
                     {
                        setupSuccessful = NetworkManagement.SetNetworkAdapterIpAddress(networkAdapterConfiguration, networkAdapterIp, networkAdapterSubnetMask, ref errMsg);

                        indentation = Common.getIndentation(1);
                        msg = "\n" + indentation + "Setting IP=" + networkAdapterIp + " and subnet=" + networkAdapterSubnetMask + " for network adapter at PCI Location " + pciLocation;

                        if (setupSuccessful)
                        {
                           // set font to default text and color
                           textProp.textFont = defaultTextProp.textFont;
                           textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
                           textProp.wordIndex = 0;
                           textProp.wordCount = 2;
                           // set font style
                           textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                           textPropList2.Add(textProp);

                           msg2 = " - SUCCESS";
                        }
                        else
                        {
                           // set font to default text and color
                           textProp.textFont = defaultTextProp.textFont;
                           textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
                           textProp.wordIndex = 0;
                           textProp.wordCount = 2;
                           // set font style
                           textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                           textPropList2.Add(textProp);

                           msg2 = " - FAILED. " + errMsg;
                        }

                        UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
                        UpdateStatusDisplayAndLogEvent(msg2, msg2, textPropList2);
                     }

                     if (setupSuccessful && networkAdapterDefaultGateway.Length > 0)
                     {
                        setupSuccessful = NetworkManagement.SetNetworkAdapterDefaultGateway(networkAdapterConfiguration, networkAdapterDefaultGateway, ref errMsg);

                        indentation = Common.getIndentation(1);
                        msg = "\n" + indentation + "Setting default gateway=" + networkAdapterDefaultGateway + " for network adapter at PCI Location " + pciLocation;

                        if (setupSuccessful)
                        {
                           // set font to default text and color
                           textProp.textFont = defaultTextProp.textFont;
                           textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
                           textProp.wordIndex = 0;
                           textProp.wordCount = 2;
                           // set font style
                           textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                           textPropList2.Add(textProp);

                           msg2 = " - SUCCESS";
                        }
                        else
                        {
                           // set font to default text and color
                           textProp.textFont = defaultTextProp.textFont;
                           textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
                           textProp.wordIndex = 0;
                           textProp.wordCount = 2;
                           // set font style
                           textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                           textPropList2.Add(textProp);

                           msg2 = " - FAILED. " + errMsg;
                        }

                        UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
                        UpdateStatusDisplayAndLogEvent(msg2, msg2, textPropList2);
                     }

                     if (setupSuccessful && dnsServers.Count > 0)
                     {
                        setupSuccessful = NetworkManagement.SetNetworkAdapterDnsServers(networkAdapter, networkAdapterConfiguration, dnsServers, ref errMsg);

                        indentation = Common.getIndentation(1);
                        msg = "\n" + indentation + "Setting DNS Server1=" + dnsServers[0];

                        if (dnsServers.Count > 1)
                           msg += " and Server2=" + dnsServers[1];

                        msg += " for network adapter at PCI Location " + pciLocation;

                        if (setupSuccessful)
                        {
                           // set font to default text and color
                           textProp.textFont = defaultTextProp.textFont;
                           textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
                           textProp.wordIndex = 0;
                           textProp.wordCount = 2;
                           // set font style
                           textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                           textPropList2.Add(textProp);

                           msg2 = " - SUCCESS";
                        }
                        else
                        {
                           // set font to default text and color
                           textProp.textFont = defaultTextProp.textFont;
                           textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
                           textProp.wordIndex = 0;
                           textProp.wordCount = 2;
                           // set font style
                           textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                           textPropList2.Add(textProp);

                           msg2 = " - FAILED. " + errMsg;
                        }

                        UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
                        UpdateStatusDisplayAndLogEvent(msg2, msg2, textPropList2);
                     }
                  }
               }

               if (!setupSuccessful)
                  break;
            }
         }

         return setupSuccessful;
      }

      // get all the necessary info if user choose to verify software by looking at the registry
      public void getNicInfo(List<ConfigFileManager.Ini_KeyValue<string>> iniKeys,
         ref string networkAdapterName,
         ref string networkAdapterIp, ref string networkAdapterSubnetMask,
         ref string networkAdapterDefaultGateway, ref string networkAdapterLinkSpeed,
         ref bool enableDhcp, ref List<string> dnsServers)
      {
         // for every key specified for the app to be installed/checked
         foreach (ConfigFileManager.Ini_KeyValue<string> iniKey in iniKeys)
         {
            if (Regex.IsMatch(iniKey.iniKeyName, @"nic\d+_adapter_name$", RegexOptions.IgnoreCase))
            {
               networkAdapterName = iniKey.iniValue;
            }
            else if (Regex.IsMatch(iniKey.iniKeyName, @"nic\d+_ip_and_subnet$", RegexOptions.IgnoreCase))
            {
               string[] ips = iniKey.iniValue.Split(',');
               networkAdapterIp = ips[0].Trim();
               networkAdapterSubnetMask = ips[1].Trim();
            }
            else if (Regex.IsMatch(iniKey.iniKeyName, @"nic\d+_default_gateway$", RegexOptions.IgnoreCase))
            {
               networkAdapterDefaultGateway = iniKey.iniValue;
            }
            else if (Regex.IsMatch(iniKey.iniKeyName, @"nic\d+_link_speed$", RegexOptions.IgnoreCase))
            {
               networkAdapterLinkSpeed = iniKey.iniValue;
            }
            else if (Regex.IsMatch(iniKey.iniKeyName, @"nic\d+_enable_dhcp$", RegexOptions.IgnoreCase))
            {
               if (String.Equals(iniKey.iniValue, "true", StringComparison.OrdinalIgnoreCase))
                  enableDhcp = true;
               else
                  enableDhcp = false;
            }
            else if (Regex.IsMatch(iniKey.iniKeyName, @"nic\d+_dns_servers$", RegexOptions.IgnoreCase))
            {
               string[] ips = iniKey.iniValue.Split(',');
               ips[0] = ips[0].Trim();

               if (ips.Length > 1)
                  ips[1] = ips[1].Trim();

               dnsServers = new List<string>(ips);
            }
         }
      }

      bool verifyConfigInfo()
      {
         bool setupSuccessful = true;
         ConfigFileManager.Ini_KeyValue<string> iniVal = new ConfigFileManager.Ini_KeyValue<string>("");
         string indentation = String.Empty;
         string msg;

         List<CommonLib.Windows.Forms.TextFormat.TextFontAndColor> textPropList = new List<CommonLib.Windows.Forms.TextFormat.TextFontAndColor>();

         // for every app name to be installed, verify that each app name has the required information specified in the INI file
         foreach (KeyValuePair<ConfigFileManager.Ini_KeyValue<string>, List<ConfigFileManager.Ini_KeyValue<string>>> entry in networkAdapterPciLocationToVarious)
         {
            if (!Regex.IsMatch(entry.Key.iniValue, @"\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*", RegexOptions.IgnoreCase))
            {
               indentation = Common.getIndentation(1);
               msg = "\n" + indentation + "- FAILED. "
                  + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
                  + "\n" + indentation + "Section: " + entry.Key.iniSectionName
                  + "\n" + indentation + "Key: " + entry.Key.iniKeyName
                  + "\n" + indentation + "Value: " + entry.Key.iniValue
                  + "\n" + indentation + "Error Description: The value is invalid the INI file. The value must be in format: #,#,# (i.e.: 1,25,0)";

               Common.formatConfigIniFailureMessage(msg, textPropList);

               UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

               setupSuccessful = false;

               break;
            }

            // for every key specified for the app to be installed
            foreach (ConfigFileManager.Ini_KeyValue<string> iniKey in entry.Value)
            {
               if (Regex.IsMatch(iniKey.iniKeyName, @"(nic\d+)_link_speed$", RegexOptions.IgnoreCase))
               {
                  uint linkSpeed = 0;

                  if (iniKey.iniValue.Length == 0 || !UInt32.TryParse(iniKey.iniValue, out linkSpeed))
                  {
                     indentation = Common.getIndentation(1);
                     msg = "\n" + indentation + "- FAILED. "
                        + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
                        + "\n" + indentation + "Section: " + iniKey.iniSectionName
                        + "\n" + indentation + "Key: " + iniKey.iniKeyName
                        + "\n" + indentation + "Value: " + iniKey.iniValue
                        + "\n" + indentation + "Error Description: The value is invalid the INI file. Value must be a number";

                     Common.formatConfigIniFailureMessage(msg, textPropList);

                     UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

                     setupSuccessful = false;

                     break;
                  }
               }
               else if (Regex.IsMatch(iniKey.iniKeyName, @"nic\d+_adapter_name", RegexOptions.IgnoreCase))
               {
                  if (iniKey.iniValue.Length == 0)
                  {
                     indentation = Common.getIndentation(1);
                     msg = "\n" + indentation + "- FAILED. "
                        + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
                        + "\n" + indentation + "Section: " + iniKey.iniSectionName
                        + "\n" + indentation + "Key: " + iniKey.iniKeyName
                        + "\n" + indentation + "Value: " + iniKey.iniValue
                        + "\n" + indentation + "Error Description: The value is invalid the INI file.";

                     Common.formatConfigIniFailureMessage(msg, textPropList);

                     UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

                     setupSuccessful = false;

                     break;
                  }
               }
               else if (Regex.IsMatch(iniKey.iniKeyName, @"nic\d+_ip_and_subnet", RegexOptions.IgnoreCase))
               {
                  if (iniKey.iniValue.Length == 0)
                  {
                     indentation = Common.getIndentation(1);
                     msg = "\n" + indentation + "- FAILED. "
                        + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
                        + "\n" + indentation + "Section: " + iniKey.iniSectionName
                        + "\n" + indentation + "Key: " + iniKey.iniKeyName
                        + "\n" + indentation + "Value: " + iniKey.iniValue
                        + "\n" + indentation + "Error Description: The value is invalid the INI file.";

                     Common.formatConfigIniFailureMessage(msg, textPropList);

                     UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

                     setupSuccessful = false;

                     break;
                  }
                  else
                  {
                     string[] ips = iniKey.iniValue.Split(',');
                     ips[0] = ips[0].Trim();

                     if (ips.Length > 1)
                        ips[1] = ips[1].Trim();
                     List<string> ipList = new List<string>(ips);

                     if (ipList.Count != 2)
                     {
                        indentation = Common.getIndentation(1);
                        msg = "\n" + indentation + "- FAILED. "
                           + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
                           + "\n" + indentation + "Section: " + iniKey.iniSectionName
                           + "\n" + indentation + "Key: " + iniKey.iniKeyName
                           + "\n" + indentation + "Value: " + iniKey.iniValue
                           + "\n" + indentation + "Error Description: The value is invalid the INI file. Expecting IP address and subnet mask separated by comma";

                        Common.formatConfigIniFailureMessage(msg, textPropList);

                        UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

                        setupSuccessful = false;

                        break;
                     }
                     else
                     {
                        if (!StringManip.IsValidIPv4(ips[0]))
                        {
                           indentation = Common.getIndentation(1);
                           msg = "\n" + indentation + "- FAILED. "
                              + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
                              + "\n" + indentation + "Section: " + iniKey.iniSectionName
                              + "\n" + indentation + "Key: " + iniKey.iniKeyName
                              + "\n" + indentation + "Value: " + iniKey.iniValue
                              + "\n" + indentation + "Error Description: The value is invalid the INI file. The IP specified is an invalid IPv4 address.";

                           Common.formatConfigIniFailureMessage(msg, textPropList);

                           UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

                           setupSuccessful = false;

                           break;
                        }
                        else if (ipList.Count > 1 && !StringManip.IsValidIPv4(ips[1]))
                        {
                           indentation = Common.getIndentation(1);
                           msg = "\n" + indentation + "- FAILED. "
                              + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
                              + "\n" + indentation + "Section: " + iniKey.iniSectionName
                              + "\n" + indentation + "Key: " + iniKey.iniKeyName
                              + "\n" + indentation + "Value: " + iniKey.iniValue
                              + "\n" + indentation + "Error Description: The value is invalid the INI file. The subnet mask specified is an invalid IPv4 address.";

                           Common.formatConfigIniFailureMessage(msg, textPropList);

                           UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

                           setupSuccessful = false;

                           break;
                        }
                     }
                  }
               }
               else if (Regex.IsMatch(iniKey.iniKeyName, @"nic\d+_default_gateway", RegexOptions.IgnoreCase))
               {
                  if (iniKey.iniValue.Length == 0)
                  {
                     indentation = Common.getIndentation(1);
                     msg = "\n" + indentation + "- FAILED. "
                        + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
                        + "\n" + indentation + "Section: " + iniKey.iniSectionName
                        + "\n" + indentation + "Key: " + iniKey.iniKeyName
                        + "\n" + indentation + "Value: " + iniKey.iniValue
                        + "\n" + indentation + "Error Description: The value is invalid the INI file.";

                     Common.formatConfigIniFailureMessage(msg, textPropList);

                     UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

                     setupSuccessful = false;

                     break;
                  }
                  else
                  {
                     if (!StringManip.IsValidIPv4(iniKey.iniValue))
                     {
                        indentation = Common.getIndentation(1);
                        msg = "\n" + indentation + "- FAILED. "
                           + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
                           + "\n" + indentation + "Section: " + iniKey.iniSectionName
                           + "\n" + indentation + "Key: " + iniKey.iniKeyName
                           + "\n" + indentation + "Value: " + iniKey.iniValue
                           + "\n" + indentation + "Error Description: The value is invalid the INI file. The gateway specified is an invalid IPv4 address.";

                        Common.formatConfigIniFailureMessage(msg, textPropList);

                        UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

                        setupSuccessful = false;

                        break;
                     }
                  }
               }
               else if (Regex.IsMatch(iniKey.iniKeyName, @"nic\d+_dns_servers", RegexOptions.IgnoreCase))
               {
                  if (iniKey.iniValue.Length == 0)
                  {
                     indentation = Common.getIndentation(1);
                     msg = "\n" + indentation + "- FAILED. "
                        + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
                        + "\n" + indentation + "Section: " + iniKey.iniSectionName
                        + "\n" + indentation + "Key: " + iniKey.iniKeyName
                        + "\n" + indentation + "Value: " + iniKey.iniValue
                        + "\n" + indentation + "Error Description: The value is invalid the INI file.";

                     Common.formatConfigIniFailureMessage(msg, textPropList);

                     UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

                     setupSuccessful = false;

                     break;
                  }
                  else
                  {
                     string[] ips = iniKey.iniValue.Split(',');
                     ips[0] = ips[0].Trim();

                     if (ips.Length > 1)
                        ips[1] = ips[1].Trim();

                     List<string> ipList = new List<string>(ips);

                     if (ipList.Count > 2)
                     {
                        indentation = Common.getIndentation(1);
                        msg = "\n" + indentation + "- FAILED. "
                           + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
                           + "\n" + indentation + "Section: " + iniKey.iniSectionName
                           + "\n" + indentation + "Key: " + iniKey.iniKeyName
                           + "\n" + indentation + "Value: " + iniKey.iniValue
                           + "\n" + indentation + "Error Description: The value is invalid the INI file. Expecting at least one DNS server, maximum 2 separated by comma";

                        Common.formatConfigIniFailureMessage(msg, textPropList);

                        UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

                        setupSuccessful = false;

                        break;
                     }
                     else
                     {
                        if (!StringManip.IsValidIPv4(ips[0]))
                        {
                           indentation = Common.getIndentation(1);
                           msg = "\n" + indentation + "- FAILED. "
                              + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
                              + "\n" + indentation + "Section: " + iniKey.iniSectionName
                              + "\n" + indentation + "Key: " + iniKey.iniKeyName
                              + "\n" + indentation + "Value: " + iniKey.iniValue
                              + "\n" + indentation + "Error Description: The value is invalid the INI file. The 1st DNS Server specified is an invalid IPv4 address.";

                           Common.formatConfigIniFailureMessage(msg, textPropList);

                           UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

                           setupSuccessful = false;

                           break;
                        }
                        else if (ipList.Count > 1 && !StringManip.IsValidIPv4(ips[1]))
                        {
                           indentation = Common.getIndentation(1);
                           msg = "\n" + indentation + "- FAILED. "
                              + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
                              + "\n" + indentation + "Section: " + iniKey.iniSectionName
                              + "\n" + indentation + "Key: " + iniKey.iniKeyName
                              + "\n" + indentation + "Value: " + iniKey.iniValue
                              + "\n" + indentation + "Error Description: The value is invalid the INI file. The 2nd DNS Server specified is an invalid IPv4 address.";

                           Common.formatConfigIniFailureMessage(msg, textPropList);

                           UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

                           setupSuccessful = false;

                           break;
                        }
                     }
                  }
               }
            }

            if (!setupSuccessful)
               break;
         }

         return setupSuccessful;
      }
   }
}
