using System.IO;
using UnityEditor;
using UnityEngine;
using Comgreate;

namespace BingoBrain.Editor
{
    public class BuildSome
    {
        public const string AssetBundleRootPath = "Assets/AssetHotFix/";
        public static readonly string AssetBundleBuildOutputPath =
            $"{Application.dataPath}/../AssetBundle/{AssetBundlesName}";
        public const string AssetBundlesName = "AssetBundles";
        public const string AssetBundleSuffix = ".assetbundle";
        public const string AssetBundlePassword = "4s2f6ac15sa6ds45";
        
        [MenuItem("Tools/Build")]
        public static void BuildAssetBundle()
        {
            AssetBundleBuildKit.ClearAssetBundlesName();

            AssetBundleBuildKit.SetAssetBundlesName(AssetBundleRootPath);

            EditorApplication.isPlaying = false;

            var dir = AssetBundleBuildOutputPath;

            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            else
            {
                Directory.Delete(dir, true);

                Directory.CreateDirectory(dir);
            }


            var buildTarget = EditorUserBuildSettings.activeBuildTarget;

            var manifest = BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.ChunkBasedCompression,
                buildTarget);
            AssetDatabase.Refresh();

            EncryptAssetBundle();

            BuildAssetBundleFileIndex(manifest);

            Debug.Log($"[ Jarvis ] [ AssetBundle构建 ] 平台: {buildTarget.ToString()} 打包完成");

            Application.OpenURL(dir + "/..");
        }


        private static void EncryptAssetBundle()
        {
            var dir = AssetBundleBuildOutputPath;

            var filePaths = Directory.GetFiles(dir, $"*{AssetBundleSuffix}",
                SearchOption.TopDirectoryOnly);


            var encryptPath = $"{Application.dataPath}/../AssetBundlesEncrypt";

            if (!Directory.Exists(encryptPath))
            {
                Directory.CreateDirectory(encryptPath);
            }
            else
            {
                Directory.Delete(encryptPath, true);

                Directory.CreateDirectory(encryptPath);
            }

            foreach (var assetBundleFile in filePaths)
            {
                if (!assetBundleFile.EndsWith(".meta") && !assetBundleFile.Contains(".DS_Store"))
                {
                    var assetBundleName = assetBundleFile.Replace(dir, string.Empty).Replace("\\", "");
                    var encryptFilePath = Path.Combine(encryptPath, assetBundleName);
                    AESForFileKit.EncryptFile(assetBundleFile, encryptFilePath,
                        AssetBundlePassword);

                    File.Copy(encryptFilePath, Path.Combine(dir, assetBundleName), true);
                }
            }


            Directory.Delete(encryptPath, true);
        }
        public const string AssetHotFixFileName = "AssetHotFixFile.txt";

        private static void BuildAssetBundleFileIndex(AssetBundleManifest manifest)
        {
            var dir = AssetBundleBuildOutputPath;
            var dirFile = $"{AssetBundleBuildOutputPath}/../";

            var filePath = Path.Combine(dirFile, AssetHotFixFileName);

            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }


            var filePaths = Directory.GetFiles(dir, $"*{AssetBundleSuffix}",
                SearchOption.TopDirectoryOnly);

            using var fileStream = new FileStream(filePath, FileMode.CreateNew);

            using var streamWriter = new StreamWriter(fileStream);

            var totalAssetBundlePath = $"{dir}/{AssetBundlesName}";

            var totalAssetBundleManifestPath = $"{dir}/{AssetBundlesManifestName}";

            var totalMD5 = MD5Kit.GetFileMD5(totalAssetBundlePath);
            streamWriter.WriteLine(GetAssetBundleFileIndex(AssetBundlesName, totalMD5));

            var manifestMD5 = MD5Kit.GetFileMD5(totalAssetBundleManifestPath);
            streamWriter.WriteLine(GetAssetBundleFileIndex(AssetBundlesManifestName,
                manifestMD5));
            foreach (var assetBundleFile in filePaths)
            {
                if (!assetBundleFile.EndsWith(".meta") && !assetBundleFile.Contains(".DS_Store"))
                {
                    var fileMD5 = MD5Kit.GetFileMD5(assetBundleFile);

                    var assetBundleName = assetBundleFile.Replace(dir, string.Empty).Replace("\\", "");

                    streamWriter.WriteLine(GetAssetBundleFileIndex(assetBundleName, fileMD5));
                }
            }
        }


        private static string GetAssetBundleFileIndex(string assetBundleName, string assetBundleFileMD5)
        {
            return $"{assetBundleName}{AssetBundleSplitChar}{assetBundleFileMD5}";
        }
        
        public const string ManifestSuffix = ".manifest";
        public static readonly string AssetBundlesManifestName = $"{AssetBundlesName}{ManifestSuffix}";
        public static readonly string AssetBundleSplitChar = "|";
    }
}