using System;
using System.IO;
using UnityEditor;
using System.Diagnostics;

namespace EngineSdkConverter.Unity.Editor
{
    public class Result
    {
        /// <summary>
        /// Standard output stream from command line.
        /// </summary>
        public string StandardOutput;

        /// <summary>
        /// Standard error stream from command line. 
        /// </summary>
        public string StandardError;

        /// <summary>
        /// Exit code returned from command line.
        /// </summary>
        public int ExitCode;

        /// <summary>
        /// The description of the result that can be used for error logging.
        /// </summary>
        public string Message;
    }

    public class EngineSdkConverterUtils
    {
        const string TAG = "EnginSdkConverterUtils ";

        static public string GetFilePathByAssetName(string assetName)
        {
            var assetGuids = AssetDatabase.FindAssets(assetName);
            string retPath = "";
            foreach (var guid in assetGuids)
            {
                retPath = AssetDatabase.GUIDToAssetPath(guid);
                if (File.Exists(retPath))
                {
                    retPath = Path.Combine(retPath);
                    break;
                }
                else
                {
                    retPath = "";
                }
            }
            return retPath;
        }

        public static Result RunShell(string toolPath, string arguments, string workingDirectory)
        {
            var stdoutFileName = Path.GetTempFileName();
            var stderrFileName = Path.GetTempFileName();

            var process = new Process();
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = false;
            process.StartInfo.RedirectStandardInput = false;
            process.StartInfo.RedirectStandardOutput = false;
            process.StartInfo.RedirectStandardError = false;

            process.StartInfo.EnvironmentVariables["LANG"] = "en_US.UTF-8";
            process.StartInfo.EnvironmentVariables["PATH"] = $"{Environment.GetEnvironmentVariable("PATH")}:/usr/local/bin";

            process.StartInfo.WorkingDirectory = workingDirectory;
            process.StartInfo.FileName = "bash";
            string argumentsFormat = string.Format("-l -c '\"{0}\" {1} 1> {2} 2> {3}'", toolPath, arguments, stdoutFileName, stderrFileName);
            process.StartInfo.Arguments = argumentsFormat;
            process.Start();

            process.WaitForExit();

            var stdout = File.ReadAllText(stdoutFileName);
            var stderr = File.ReadAllText(stderrFileName);

            File.Delete(stdoutFileName);
            File.Delete(stderrFileName);

            var result = new Result();
            result.StandardOutput = stdout;
            result.StandardError = stderr;
            result.ExitCode = process.ExitCode;

            var messagePrefix = result.ExitCode == 0 ? "Command executed successfully" : "Failed to run command";
            result.Message = string.Format("{0}: '{1} {2}'\nstdout: {3}\nstderr: {4}\nExit code: {5}", messagePrefix, toolPath, arguments, stdout, stderr, process.ExitCode);

            return result;
        }

        public static Result RunPython(string scriptPath, string arguments, string workingDirectory)
        {
            var stdoutFileName = Path.GetTempFileName();
            var stderrFileName = Path.GetTempFileName();

            var process = new Process();
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = false;
            process.StartInfo.RedirectStandardInput = false;
            process.StartInfo.RedirectStandardOutput = false;
            process.StartInfo.RedirectStandardError = false;

            process.StartInfo.EnvironmentVariables["LANG"] = "en_US.UTF-8";
            process.StartInfo.EnvironmentVariables["PATH"] = $"{Environment.GetEnvironmentVariable("PATH")}:/usr/local/bin";

            process.StartInfo.WorkingDirectory = workingDirectory;
            process.StartInfo.FileName = "bash";

            // 直接调用 Python3 并保证参数安全
            string argumentsFormat = $"-l -c 'python3 \"{scriptPath}\" {arguments} 1> \"{stdoutFileName}\" 2> \"{stderrFileName}\"'";
            process.StartInfo.Arguments = argumentsFormat;

            process.Start();
            process.WaitForExit();

            var stdout = File.ReadAllText(stdoutFileName);
            var stderr = File.ReadAllText(stderrFileName);

            File.Delete(stdoutFileName);
            File.Delete(stderrFileName);

            var result = new Result
            {
                StandardOutput = stdout,
                StandardError = stderr,
                ExitCode = process.ExitCode,
                Message = $"{(process.ExitCode == 0 ? "Command executed successfully" : "Failed to run command")}: 'python3 {scriptPath} {arguments}'\nstdout: {stdout}\nstderr: {stderr}\nExit code: {process.ExitCode}"
            };

            return result;
        }

        public static void CopyDirectory(string sourceDir, string destDir, bool replace)
        {
            // 确保目标文件夹存在
            if (!Directory.Exists(destDir))
            {
                Directory.CreateDirectory(destDir);
            }

            // 复制所有文件
            foreach (var file in Directory.GetFiles(sourceDir))
            {
                string destFilePath = Path.Combine(destDir, Path.GetFileName(file));
                File.Copy(file, destFilePath, replace); // true 表示覆盖已有文件
            }

            // 递归复制子文件夹
            foreach (var subDir in Directory.GetDirectories(sourceDir))
            {
                string newDestDir = Path.Combine(destDir, Path.GetFileName(subDir));
                CopyDirectory(subDir, newDestDir, replace);
            }
        }
    }
}