using HybridCLR.Editor.Commands;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEditor.EditorTools;
using UnityEngine;
using EditorTools = YooAsset.Editor.EditorTools;

namespace HybridCLR.Editor
{
    public static class AssetBundleBuildCommand
    {
        public static string HybridCLRBuildCacheDir => Application.dataPath + "/HybridCLRBuildCache";

        public static string AssetBundleOutputDir => $"{HybridCLRBuildCacheDir}/AssetBundleOutput";

        public static string AssetBundleSourceDataTempDir => $"{HybridCLRBuildCacheDir}/AssetBundleSourceData";

        public static string GetAssetBundleOutputDirByTarget(BuildTarget target)
        {
            return $"{AssetBundleOutputDir}/{target}";
        }
        
        public static string YooAssetCodeDll = Application.dataPath + "/Res/CodeDll/";

        public static string GetAssetBundleTempDirByTarget(BuildTarget target)
        {
            return $"{AssetBundleSourceDataTempDir}/{target}";
        }

        public static string ToRelativeAssetPath(string s)
        {
            return s.Substring(s.IndexOf("Assets/"));
        }

        /// <summary>
        /// 将HotFix.dll和HotUpdatePrefab.prefab打入common包.
        /// 将HotUpdateScene.unity打入scene包.
        /// </summary>
        /// <param name="tempDir"></param>
        /// <param name="outputDir"></param>
        /// <param name="target"></param>
        private static void BuildAssetBundles(string tempDir, string outputDir, BuildTarget target)
        {
            Directory.CreateDirectory(tempDir);
            Directory.CreateDirectory(outputDir);

            if (Directory.Exists(YooAssetCodeDll))
            {
                EditorTools.DeleteDirectory(YooAssetCodeDll);
            }
            Directory.CreateDirectory(YooAssetCodeDll);
            
            //step 1
            CompileDllCommand.CompileDll(target);
            
            //step 2
            PrebuildCommand.GenerateAll();

            //step 3 copy
            ET.BuildEditor.BuildModelAndHotfix();
            //hotfix.dll不使用默认的打包,ET里面加了些骚操作
            // List<string> notSceneAssets = new List<string>();
            /*string hotfixDllSrcDir = SettingsUtil.GetHotUpdateDllsOutputDirByTarget(target);
            foreach (var dll in SettingsUtil.HotUpdateAssemblyFiles)
            {
                string dllPath = $"{hotfixDllSrcDir}/{dll}";
                string dllBytesPath = $"{YooAssetCodeDll}/{dll}.bytes";
                File.Copy(dllPath, dllBytesPath, true);
                // notSceneAssets.Add(dllBytesPath);
                Debug.Log($"[BuildAssetBundles] copy hotfix dll {dllPath} -> {dllBytesPath}");
            }*/

            //step 4
            string aotDllDir = SettingsUtil.GetAssembliesPostIl2CppStripDir(target);

            ConfigStringList manifest = AssetDatabase.LoadAssetAtPath("Assets/Res/Config/HotUpdateAOTDlls.asset", typeof(ConfigStringList)) as ConfigStringList;
            if (manifest == null)
            {
                throw new Exception($"resource asset:{nameof(ConfigStringList)} 配置不存在,请在Resources目录下创建");
            }
            List<string> AOTMetaAssemblies= (manifest.List?? Array.Empty<string>()).ToList();
            foreach (var dll in AOTMetaAssemblies)
            {
                string dllPath = $"{aotDllDir}/{dll}";
                if (!File.Exists(dllPath))
                {
                    Debug.LogError($"ab中添加AOT补充元数据dll:{dllPath} 时发生错误,文件不存在。裁剪后的AOT dll在BuildPlayer时才能生成,因此需要你先构建一次游戏App后再打包。");
                    continue;
                }
                string dllBytesPath = $"{YooAssetCodeDll}/{dll}.bytes";
                File.Copy(dllPath, dllBytesPath, true);
                // notSceneAssets.Add(dllBytesPath);
                Debug.Log($"[BuildAssetBundles] copy AOT dll {dllPath} -> {dllBytesPath}");
            }

            // string testPrefab = $"{Application.dataPath}/Prefabs/HotUpdatePrefab.prefab";
            // notSceneAssets.Add(testPrefab);
            // AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
            //
            // List<AssetBundleBuild> abs = new List<AssetBundleBuild>();
            // AssetBundleBuild notSceneAb = new AssetBundleBuild
            // {
            //     assetBundleName = "common",
            //     assetNames = notSceneAssets.Select(s => ToRelativeAssetPath(s)).ToArray(),
            // };
            // abs.Add(notSceneAb);
            //
            // UnityEditor.BuildPipeline.BuildAssetBundles(outputDir, abs.ToArray(), BuildAssetBundleOptions.None, target);
            //
            // AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
            //
            // string streamingAssetPathDst = $"{Application.streamingAssetsPath}";
            // Directory.CreateDirectory(streamingAssetPathDst);
            //
            // foreach (var ab in abs)
            // {
            //     AssetDatabase.CopyAsset(ToRelativeAssetPath($"{outputDir}/{ab.assetBundleName}"),
            //         ToRelativeAssetPath($"{streamingAssetPathDst}/{ab.assetBundleName}"));
            // }
        }

        public static void BuildAssetBundleByTarget(BuildTarget target)
        {
            BuildAssetBundles(GetAssetBundleTempDirByTarget(target), GetAssetBundleOutputDirByTarget(target), target);
        }

        [MenuItem("HybridCLR/CollectorDll/ActiveBuildTarget")]
        public static void BuildSceneAssetBundleActiveBuildTarget()
        {
            BuildAssetBundleByTarget(EditorUserBuildSettings.activeBuildTarget);
        }

        // [MenuItem("HybridCLR/CollectorDll/Win64")]
        // public static void BuildSceneAssetBundleWin64()
        // {
        //     var target = BuildTarget.StandaloneWindows64;
        //     BuildAssetBundleByTarget(target);
        // }
        //
        // [MenuItem("HybridCLR/CollectorDll/Win32")]
        // public static void BuildSceneAssetBundleWin32()
        // {
        //     var target = BuildTarget.StandaloneWindows;
        //     BuildAssetBundleByTarget(target);
        // }
        //
        // [MenuItem("HybridCLR/CollectorDll/Android")]
        // public static void BuildSceneAssetBundleAndroid()
        // {
        //     var target = BuildTarget.Android;
        //     BuildAssetBundleByTarget(target);
        // }
        //
        // [MenuItem("HybridCLR/CollectorDll/IOS")]
        // public static void BuildSceneAssetBundleIOS()
        // {
        //     var target = BuildTarget.iOS;
        //     BuildAssetBundleByTarget(target);
        // }
    }
}