using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

namespace AxCopilot.Services.Agent;

public class FileManageTool : IAgentTool
{
	public string Name => "file_manage";

	public string Description => "Manage files and directories. Actions: 'move' — move file/folder to destination; 'copy' — copy file/folder to destination; 'rename' — rename file/folder; 'delete' — delete file (requires Ask permission); 'mkdir' — create directory recursively.";

	public ToolParameterSchema Parameters
	{
		get
		{
			ToolParameterSchema toolParameterSchema = new ToolParameterSchema();
			Dictionary<string, ToolProperty> dictionary = new Dictionary<string, ToolProperty>();
			ToolProperty obj = new ToolProperty
			{
				Type = "string",
				Description = "Action to perform"
			};
			int num = 5;
			List<string> list = new List<string>(num);
			CollectionsMarshal.SetCount(list, num);
			Span<string> span = CollectionsMarshal.AsSpan(list);
			span[0] = "move";
			span[1] = "copy";
			span[2] = "rename";
			span[3] = "delete";
			span[4] = "mkdir";
			obj.Enum = list;
			dictionary["action"] = obj;
			dictionary["path"] = new ToolProperty
			{
				Type = "string",
				Description = "Source file/folder path"
			};
			dictionary["destination"] = new ToolProperty
			{
				Type = "string",
				Description = "Destination path (for move/copy/rename)"
			};
			toolParameterSchema.Properties = dictionary;
			num = 2;
			List<string> list2 = new List<string>(num);
			CollectionsMarshal.SetCount(list2, num);
			Span<string> span2 = CollectionsMarshal.AsSpan(list2);
			span2[0] = "action";
			span2[1] = "path";
			toolParameterSchema.Required = list2;
			return toolParameterSchema;
		}
	}

	public async Task<ToolResult> ExecuteAsync(JsonElement args, AgentContext context, CancellationToken ct = default(CancellationToken))
	{
		string action = args.GetProperty("action").GetString() ?? "";
		string rawPath = args.GetProperty("path").GetString() ?? "";
		JsonElement d;
		string dest = (args.TryGetProperty("destination", out d) ? (d.GetString() ?? "") : "");
		string path = (Path.IsPathRooted(rawPath) ? rawPath : Path.Combine(context.WorkFolder, rawPath));
		if (!context.IsPathAllowed(path))
		{
			return ToolResult.Fail("경로 접근 차단: " + path);
		}
		try
		{
			switch (action)
			{
			case "mkdir":
				Directory.CreateDirectory(path);
				return ToolResult.Ok("디렉토리 생성: " + path);
			case "delete":
				if (context.AskPermission != null && !(await context.AskPermission("file_manage(delete)", path)))
				{
					return ToolResult.Fail("사용자가 삭제를 거부했습니다.");
				}
				if (File.Exists(path))
				{
					File.Delete(path);
					return ToolResult.Ok("파일 삭제: " + path, path);
				}
				if (Directory.Exists(path))
				{
					Directory.Delete(path, recursive: true);
					return ToolResult.Ok("폴더 삭제: " + path, path);
				}
				return ToolResult.Fail("경로를 찾을 수 없습니다: " + path);
			case "move":
			case "copy":
			case "rename":
			{
				if (string.IsNullOrEmpty(dest))
				{
					return ToolResult.Fail("'" + action + "' 작업에는 'destination'이 필요합니다.");
				}
				string destPath = (Path.IsPathRooted(dest) ? dest : Path.Combine(context.WorkFolder, dest));
				if (!context.IsPathAllowed(destPath))
				{
					return ToolResult.Fail("대상 경로 접근 차단: " + destPath);
				}
				string destDir = Path.GetDirectoryName(destPath);
				if (!string.IsNullOrEmpty(destDir) && !Directory.Exists(destDir))
				{
					Directory.CreateDirectory(destDir);
				}
				if (action == "rename")
				{
					string dir = Path.GetDirectoryName(path) ?? context.WorkFolder;
					destPath = Path.Combine(dir, dest);
				}
				if (File.Exists(path))
				{
					if (action == "copy")
					{
						File.Copy(path, destPath, overwrite: true);
					}
					else
					{
						File.Move(path, destPath, overwrite: true);
					}
					return ToolResult.Ok($"{action}: {path} → {destPath}", destPath);
				}
				if (Directory.Exists(path))
				{
					if (action == "copy")
					{
						CopyDirectory(path, destPath);
					}
					else
					{
						Directory.Move(path, destPath);
					}
					return ToolResult.Ok($"{action}: {path} → {destPath}", destPath);
				}
				return ToolResult.Fail("소스 경로를 찾을 수 없습니다: " + path);
			}
			default:
				return ToolResult.Fail("Unknown action: " + action);
			}
		}
		catch (Exception ex)
		{
			return ToolResult.Fail("파일 관리 오류: " + ex.Message);
		}
	}

	private static void CopyDirectory(string src, string dst)
	{
		Directory.CreateDirectory(dst);
		string[] files = Directory.GetFiles(src);
		foreach (string text in files)
		{
			File.Copy(text, Path.Combine(dst, Path.GetFileName(text)), overwrite: true);
		}
		string[] directories = Directory.GetDirectories(src);
		foreach (string text2 in directories)
		{
			CopyDirectory(text2, Path.Combine(dst, Path.GetFileName(text2)));
		}
	}
}
