context: extern alias MySqlConnectorAlias;
  
  using System;
  using System.IO;
  using System.IO.Compression;
  using System.Linq;
  using System.Net;
  using System.Threading;
  using ACE.Common;
  
  using DouglasCrockford.JsMin;
  using Newtonsoft.Json;
  
  namespace ACE.Server
  {
      partial class Program
      {
          private static void DoOutOfBoxSetup(string configFile)
          {
              var exeLocation = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
              var configJsExample = Path.Combine(exeLocation, "Config.js.example");
              var exampleFile = new FileInfo(configJsExample);
              if (!exampleFile.Exists)
              {
                  log.Error("config.js.example Configuration file is missing.  Please copy the file config.js.example to config.js and edit it to match your needs before running ACE.");
                  throw new Exception("missing config.js configuration file");
              }
              else
              {
                  if (!IsRunningInContainer)
                  {
                      Console.WriteLine("config.js Configuration file is missing,  cloning from example file.");
                      File.Copy(configJsExample, configFile, true);
                  }
                  else
                  {
                      Console.WriteLine("config.js Configuration file is missing, ACEmulator is running in a container,  cloning from docker file.");
                      var configJsDocker = Path.Combine(exeLocation, "Config.js.docker");
                      File.Copy(configJsDocker, configFile, true);
                  }
              }
  
              var fileText = File.ReadAllText(configFile);
              var config = JsonConvert.DeserializeObject<MasterConfiguration>(new JsMinifier().Minify(fileText));
  
              Console.WriteLine("Performing setup for ACEmulator...");
              Console.WriteLine();
              Console.WriteLine();
              Console.WriteLine();
              Console.WriteLine("Welcome to ACEmulator! To configure your world for first use, please follow the instructions below. Press enter at each prompt to accept default values.");
              Console.WriteLine();
              Console.WriteLine();
  
              Console.Write($"Enter the name for your World (default: \"{config.Server.WorldName}\"): ");
              var variable = Console.ReadLine();
              if (IsRunningInContainer) variable = Environment.GetEnvironmentVariable("ACE_WORLD_NAME");
              if (!string.IsNullOrWhiteSpace(variable))
                  config.Server.WorldName = variable.Trim();
              Console.WriteLine();
  
              Console.WriteLine();
              Console.WriteLine();
              Console.WriteLine("The next two entries should use defaults, unless you have specific network environments...");
              Console.WriteLine();
              Console.WriteLine();
              Console.Write($"Enter the Host address for your World (default: \"{config.Server.Network.Host}\"): ");
              variable = Console.ReadLine();
              if (!string.IsNullOrWhiteSpace(variable))
                  config.Server.Network.Host = variable.Trim();
              Console.WriteLine();
  
              Console.Write($"Enter the Port for your World (default: \"{config.Server.Network.Port}\"): ");
              variable = Console.ReadLine();
              if (!string.IsNullOrWhiteSpace(variable))
                  config.Server.Network.Port = Convert.ToUInt32(variable.Trim());
              Console.WriteLine();
  
              Console.WriteLine();
              Console.WriteLine();
  
              Console.Write($"Enter the directory location for your DAT files (default: \"{config.Server.DatFilesDirectory}\"): ");
              variable = Console.ReadLine();
              if (IsRunningInContainer) variable = Environment.GetEnvironmentVariable("ACE_DAT_FILES_DIRECTORY");
              if (!string.IsNullOrWhiteSpace(variable))
              {
                  var path = Path.GetFullPath(variable.Trim());
                  if (!Path.EndsInDirectorySeparator(path))
                      path += Path.DirectorySeparatorChar;
                  //path = path.Replace($"{Path.DirectorySeparatorChar}", $"{Path.DirectorySeparatorChar}{Path.DirectorySeparatorChar}");
  
                  config.Server.DatFilesDirectory = path;
              }
              Console.WriteLine();
  
              Console.WriteLine();
              Console.WriteLine();
              Console.WriteLine("Next we will configure your SQL server connections. You will need to provide a database name, username and password for each.");
              Console.WriteLine("Default names for the databases are recommended, and it is also recommended you not use root for login to database. The password must not be blank.");
              Console.WriteLine("It is also recommended the SQL server be hosted on the same machine as this server, so defaults for Host and Port would be ideal as well.");
              Console.WriteLine("As before, pressing enter will use default value.");
              Console.WriteLine();
              Console.WriteLine();
  
              Console.Write($"Enter the database name for your authentication database (default: \"{config.MySql.Authentication.Database}\"): ");
              variable = Console.ReadLine();
              if (IsRunningInContainer) variable = Environment.GetEnvironmentVariable("ACE_SQL_AUTH_DATABASE_NAME");
              if (!string.IsNullOrWhiteSpace(variable))
                  config.MySql.Authentication.Database = variable.Trim();
              Console.WriteLine();
  
              Console.Write($"Enter the database name for your shard database (default: \"{config.MySql.Shard.Database}\"): ");
              variable = Console.ReadLine();
              if (IsRunningInContainer) variable = Environment.GetEnvironmentVariable("ACE_SQL_SHARD_DATABASE_NAME");
              if (!string.IsNullOrWhiteSpace(variable))
                  config.MySql.Shard.Database = variable.Trim();
              Console.WriteLine();
  
              Console.Write($"Enter the database name for your world database (default: \"{config.MySql.World.Database}\"): ");
              variable = Console.ReadLine();
              if (IsRunningInContainer) variable = Environment.GetEnvironmentVariable("ACE_SQL_WORLD_DATABASE_NAME");
              if (!string.IsNullOrWhiteSpace(variable))
                  config.MySql.World.Database = variable.Trim();
              Console.WriteLine();
  
              Console.WriteLine();
              Console.WriteLine();
              Console.Write("Typically, all three databases will be on the same SQL server, is this how you want to proceed? (Y/n) ");
              variable = Console.ReadLine();
              if (IsRunningInContainer) variable = "n";
              if (!variable.Equals("n", StringComparison.OrdinalIgnoreCase) && !variable.Equals("no", StringComparison.OrdinalIgnoreCase))
              {
                  Console.Write($"Enter the Host address for your SQL server (default: \"{config.MySql.World.Host}\"): ");
                  variable = Console.ReadLine();
                  if (!string.IsNullOrWhiteSpace(variable))
                  {
                      config.MySql.Authentication.Host = variable.Trim();
                      config.MySql.Shard.Host = variable.Trim();
                      config.MySql.World.Host = variable.Trim();
                  }
                  Console.WriteLine();
  
                  Console.Write($"Enter the Port for your SQL server (default: \"{config.MySql.World.Port}\"): ");
                  variable = Console.ReadLine();
                  if (!string.IsNullOrWhiteSpace(variable))
                  {
                      config.MySql.Authentication.Port = Convert.ToUInt32(variable.Trim());
                      config.MySql.Shard.Port = Convert.ToUInt32(variable.Trim());
                      config.MySql.World.Port = Convert.ToUInt32(variable.Trim());
                  }
                  Console.WriteLine();
              }
              else
              {
                  Console.Write($"Enter the Host address for your authentication database (default: \"{config.MySql.Authentication.Host}\"): ");
                  variable = Console.ReadLine();
                  if (IsRunningInContainer) variable = Environment.GetEnvironmentVariable("ACE_SQL_AUTH_DATABASE_HOST");
                  if (!string.IsNullOrWhiteSpace(variable))
                      config.MySql.Authentication.Host = variable.Trim();
                  Console.WriteLine();
  
                  Console.Write($"Enter the Port for your authentication database (default: \"{config.MySql.Authentication.Port}\"): ");
                  variable = Console.ReadLine();
                  if (IsRunningInContainer) variable = Environment.GetEnvironmentVariable("ACE_SQL_AUTH_DATABASE_PORT");
                  if (!string.IsNullOrWhiteSpace(variable))
                      config.MySql.Authentication.Port = Convert.ToUInt32(variable.Trim());
                  Console.WriteLine();
  
                  Console.Write($"Enter the Host address for your shard database (default: \"{config.MySql.Shard.Host}\"): ");
                  variable = Console.ReadLine();
                  if (IsRunningInContainer) variable = Environment.GetEnvironmentVariable("ACE_SQL_SHARD_DATABASE_HOST");
                  if (!string.IsNullOrWhiteSpace(variable))
                      config.MySql.Shard.Host = variable.Trim();
                  Console.WriteLine();
  
                  Console.Write($"Enter the Port for your shard database (default: \"{config.MySql.Shard.Port}\"): ");
                  variable = Console.ReadLine();
                  if (IsRunningInContainer) variable = Environment.GetEnvironmentVariable("ACE_SQL_SHARD_DATABASE_PORT");
                  if (!string.IsNullOrWhiteSpace(variable))
                      config.MySql.Shard.Port = Convert.ToUInt32(variable.Trim());
                  Console.WriteLine();
  
                  Console.Write($"Enter the Host address for your world database (default: \"{config.MySql.World.Host}\"): ");
                  variable = Console.ReadLine();
                  if (IsRunningInContainer) variable = Environment.GetEnvironmentVariable("ACE_SQL_WORLD_DATABASE_HOST");
                  if (!string.IsNullOrWhiteSpace(variable))
                      config.MySql.World.Host = variable.Trim();
                  Console.WriteLine();
  
                  Console.Write($"Enter the Port for your world database (default: \"{config.MySql.World.Port}\"): ");
                  variable = Console.ReadLine();
                  if (IsRunningInContainer) variable = Environment.GetEnvironmentVariable("ACE_SQL_WORLD_DATABASE_PORT");
                  if (!string.IsNullOrWhiteSpace(variable))
                      config.MySql.World.Port = Convert.ToUInt32(variable.Trim());
                  Console.WriteLine();
              }
  
              Console.WriteLine();
              Console.WriteLine();
              Console.Write("Typically, all three databases will be on the using the same SQL server credentials, is this how you want to proceed? (Y/n) ");
              variable = Console.ReadLine();
              if (IsRunningInContainer) variable = "y";
              if (!variable.Equals("n", StringComparison.OrdinalIgnoreCase) && !variable.Equals("no", StringComparison.OrdinalIgnoreCase))
              {
                  Console.Write($"Enter the username for your SQL server (default: \"{config.MySql.World.Username}\"): ");
                  variable = Console.ReadLine();
                  if (IsRunningInContainer) variable = Environment.GetEnvironmentVariable("MYSQL_USER");
                  if (!string.IsNullOrWhiteSpace(variable))
                  {
                      config.MySql.Authentication.Username = variable.Trim();
                      config.MySql.Shard.Username = variable.Trim();
                      config.MySql.World.Username = variable.Trim();
                  }
                  Console.WriteLine();
  
                  Console.Write($"Enter the password for your SQL server (default: \"{config.MySql.World.Password}\"): ");
                  variable = Console.ReadLine();
                  if (IsRunningInContainer) variable = Environment.GetEnvironmentVariable("MYSQL_PASSWORD");
                  if (!string.IsNullOrWhiteSpace(variable))
                  {
                      config.MySql.Authentication.Password = variable.Trim();
                      config.MySql.Shard.Password = variable.Trim();
                      config.MySql.World.Password = variable.Trim();
                  }
              }
              else
              {
                  Console.Write($"Enter the username for your authentication database (default: \"{config.MySql.Authentication.Username}\"): ");
                  variable = Console.ReadLine();
                  if (!string.IsNullOrWhiteSpace(variable))
                      config.MySql.Authentication.Username = variable.Trim();
                  Console.WriteLine();
  
                  Console.Write($"Enter the password for your authentication database (default: \"{config.MySql.Authentication.Password}\"): ");
  
gt:                 variable = Console.ReadLine();