using XGame.Editor.Asset;
using System;
using System.IO;
using UnityEditor;
using UnityEditor.Build.Pipeline;
using UnityEngine;
using UnityEngine.Build.Pipeline;

namespace XGame.Editor.Build.AssetBundles
{
    public class SbpBuildPipeline : IBuildPipeline
    {
        public bool BuildAssetBundles(UnityEditor.AssetBundleBuild[] builds)
        {
            var outputPath = PathDefine.AssetBundleOutputPath; // KFADF.FileUtil.WorkPath + "/AssetBundles";
            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }

            //LZ4压缩 | 报错中断
            //剔除文件头的Unity版本号信息 BuildAssetBundleOptions.AssetBundleStripUnityVersion
            var bundleOptions = BuildAssetBundleOptions.ChunkBasedCompression | BuildAssetBundleOptions.StrictMode;
            //            bool shouldCheckODR = EditorUserBuildSettings.activeBuildTarget == BuildTarget.iOS;
            //#if UNITY_TVOS
            //            shouldCheckODR |= EditorUserBuildSettings.activeBuildTarget == BuildTarget.tvOS;
            //#endif
            //            if (shouldCheckODR)
            //            {
            //#if ENABLE_IOS_ON_DEMAND_RESOURCES
            //                if (PlayerSettings.iOS.useOnDemandResources)
            //                    bundleOptions |= BuildAssetBundleOptions.UncompressedAssetBundle;
            //#endif
            //#if ENABLE_IOS_APP_SLICING
            //                bundleOptions |= BuildAssetBundleOptions.UncompressedAssetBundle;
            //#endif
            //            }
            return BuildAssetBundles(outputPath, builds, bundleOptions, EditorUserBuildSettings.activeBuildTarget);
        }

        public bool BuildAssetBundles(string outputPath, UnityEditor.AssetBundleBuild[] builds, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform)
        {
            BuildLog.Log($"SbpBuildPipeline. Target: {EditorUserBuildSettings.activeBuildTarget} Time: {DateTime.Now}");
            var manifest = CompatibilityBuildPipeline.BuildAssetBundles(outputPath, builds, assetBundleOptions, targetPlatform);
            if (manifest != null)
            {
                BuildLog.Log($"SbpBuildPipeline success. Time: {DateTime.Now}");
                PostBuildAssetBundles(manifest, outputPath);
                return true;
            }
            else
            {
                BuildLog.Error($"SbpBuildPipeline failed.  Time: {DateTime.Now}");
            }
            return false;
        }

        /// <summary>
        /// SBP的ab没有后缀，手动补上后缀，并且没有了 *.bunle.manifest文件，crc值需要manifest里获取
        /// </summary>
        /// <param name="manifest"></param>
        private void PostBuildAssetBundles(CompatibilityAssetBundleManifest manifest, string outputPath)
        {
            var bundleNames = manifest.GetAllAssetBundles();
            var count = bundleNames.Length;
            var crcManifest = new BundleCrcInfoManifest()
            {
                bundleInfos = new BundleCrcInfo[count]
            };
            var noVariant = string.IsNullOrEmpty(Framework.Asset.Define.BUNDLE_VARIANT);
            for (var i = 0; i < count; i++)
            {
                var bundleName = bundleNames[i];
                // bundleName不包含后缀，把子文件夹名字也去掉，方便直接拿文件名比对
                var sepIndex = bundleName.LastIndexOf('/');
                var bundleInfo = new BundleCrcInfo()
                {
                    bundleName = sepIndex >= 0 ? bundleName.Substring(sepIndex + 1) : bundleName,
                    bundleCRC = manifest.GetAssetBundleCrc(bundleName).ToString()
                };
                crcManifest.bundleInfos[i] = bundleInfo;
                if (noVariant)
                {
                    continue;
                }
                try
                {
                    var filePath = Path.Combine(outputPath, bundleName);
                    if (File.Exists(filePath))
                    {
                        UnityEditor.FileUtil.MoveFileOrDirectory(filePath, $"{filePath}.{Framework.Asset.Define.BUNDLE_VARIANT}");
                    }
                }
                catch (Exception ex)
                {
                    Debug.LogException(ex);
                }
            }
            var crcManifestPath = Path.Combine(outputPath, "BundleCrcInfoManifest.manifest");
            if (File.Exists(crcManifestPath))
            {
                File.Delete(crcManifestPath);
            }
            File.WriteAllText(crcManifestPath, crcManifest.ToString());
            BuildLog.Log($"PostBuildAssetBundles Completed. Manifest Path:{crcManifestPath}");
        }
    }
}
