using System;
using System.Diagnostics;
using System.IO;
using System.IO.IsolatedStorage;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace TeslaConsole;

internal static class Program
{
	private static Mutex sInstanceMutex = null;

	private static readonly string sExceptionFile = Path.Combine(GetCommonAppDataDirectory(), "ExceptionLog.txt");

	[STAThread]
	private static void Main(string[] args)
	{
		if (args.Length >= 1 && args[0] == "/migrateIsoStore")
		{
			try
			{
				string path = Path.Combine(GetCommonAppDataDirectory(), "local.siteconfig");
				IsolatedStorageFile machineStoreForAssembly = IsolatedStorageFile.GetMachineStoreForAssembly();
				if (machineStoreForAssembly.GetFileNames("local.siteconfig").Length > 0)
				{
					using (IsolatedStorageFileStream isolatedStorageFileStream = new IsolatedStorageFileStream("local.siteconfig", FileMode.Open, FileAccess.Read, FileShare.Read, machineStoreForAssembly))
					{
						using FileStream fileStream = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.Read);
						byte[] array = new byte[4096];
						int count;
						while ((count = isolatedStorageFileStream.Read(array, 0, array.Length)) > 0)
						{
							fileStream.Write(array, 0, count);
						}
						isolatedStorageFileStream.Close();
						fileStream.Close();
					}
					machineStoreForAssembly.DeleteFile("local.siteconfig");
				}
				Environment.Exit(0);
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.ToString());
				Environment.Exit(1);
			}
		}
		sInstanceMutex = new Mutex(initiallyOwned: false, "TeslaConsole1Instance", out var createdNew);
		if (!createdNew)
		{
			MessageBox.Show("Another instance of the Tesla Console is alread open.", "Tesla Console Open", MessageBoxButtons.OK);
			return;
		}
		if (!Debugger.IsAttached)
		{
			Application.ThreadException += Application_ThreadException;
		}
		Application.EnableVisualStyles();
		Application.SetCompatibleTextRenderingDefault(defaultValue: false);
		Application.Run(new TeslaConsoleForm());
	}

	internal static string GetCommonAppDataDirectory()
	{
		string text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Tesla Console");
		if (!Directory.Exists(text))
		{
			Directory.CreateDirectory(text);
		}
		return text;
	}

	private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
	{
		LogExceptionAndShowDialog(e.Exception, "An unhandled exception occurred, and the console must exit.", "Unhandled Exception");
		Environment.Exit(1);
	}

	public static bool LogException(Exception ex, string generalMessage)
	{
		return LogString((generalMessage != null) ? generalMessage : "No general message available.", (ex != null) ? ex.ToString() : "The exception was null!");
	}

	public static bool LogMessage(string generalMessage)
	{
		return LogString(generalMessage, null);
	}

	private static bool LogString(string generalString, string exceptionString)
	{
		try
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("**********");
			stringBuilder.AppendLine(DateTime.Now.ToString());
			if (!string.IsNullOrEmpty(generalString))
			{
				stringBuilder.AppendLine(generalString);
			}
			if (!string.IsNullOrEmpty(exceptionString))
			{
				stringBuilder.AppendLine(exceptionString);
			}
			lock (sExceptionFile)
			{
				string commonAppDataDirectory = GetCommonAppDataDirectory();
				if (!Directory.Exists(commonAppDataDirectory))
				{
					Directory.CreateDirectory(commonAppDataDirectory);
				}
				File.AppendAllText(sExceptionFile, stringBuilder.ToString(), Encoding.UTF8);
			}
			return true;
		}
		catch (Exception)
		{
			return false;
		}
	}

	public static void LogExceptionAndShowDialog(Exception ex, string generalMessage, string messageBoxTitle)
	{
		if (LogException(ex, generalMessage))
		{
			MessageBox.Show($"{generalMessage}  The associated exception has been logged in \"{sExceptionFile}\".  Please send this file to support@elsewhenstudios.com", messageBoxTitle, MessageBoxButtons.OK);
			return;
		}
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.AppendLine((generalMessage != null) ? generalMessage : "No general message available.");
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("The associated exception could not be logged.  Please give the following information to support@elsewhenstudios.com");
		stringBuilder.AppendLine();
		stringBuilder.AppendLine((ex != null) ? ex.ToString() : "The exception was null!");
		MessageBox.Show(stringBuilder.ToString(), messageBoxTitle, MessageBoxButtons.OK);
	}
}
