using XGame.Editor.Asset;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;

namespace XGame.Editor.Build.AssetBundles
{
    /// <summary>
    /// 收集bundle引用
    /// </summary>
    internal class BundleRefsController
    {

        private BundleContext _context;
        private AssetBundleCollector _collector;
        public BundleRefsController(BundleContext context, AssetBundleCollector collector)
        {
            _context = context;
            _collector = collector;
        }

        internal void CollectForResAddressable()
        {
            _collector.CollectBundleBuilds(false);
            var assetsMap = new Dictionary<string, long>();
            var dependenciesMap = new Dictionary<long, string[]>();
            var refBundlesMap = new Dictionary<string, HashSet<long>>();
            var tmpDependencies = new HashSet<string>();
            foreach (var item in _context.bundleDataMap)
            {
                var assetNames = item.Value.assetNames;
                if (assetNames.Length == 1)
                    continue;
                var dependencies = AssetDatabase.GetDependencies(item.Value.assetNames, true);
                tmpDependencies.Clear();
                foreach (var dependency in dependencies)
                {
                    if (dependency.Contains(PathDefine.ResAddressableName) == false ||
                        Asset.FileUtil.IsFileIgnore(dependency) ||
                        assetNames.Contains(dependency))
                    {
                        continue;
                    }
                    tmpDependencies.Add(dependency);
                }
                if (tmpDependencies.Count > 0)
                {
                    var bundleId = item.Key;
                    dependenciesMap.Add(bundleId, tmpDependencies.ToArray());
                    foreach (var assetPath in assetNames)
                    {
                        assetsMap.Add(assetPath, bundleId);
                    }
                    tmpDependencies.Clear();
                }
            }
            foreach (var item in dependenciesMap)
            {
                var bundleId = item.Key;
                var dependencies = item.Value;
                foreach (var dependency in dependencies)
                {
                    if (assetsMap.TryGetValue(dependency, out var depBundleId) && depBundleId != bundleId)
                    {
                        if (!refBundlesMap.TryGetValue(dependency, out var depBundleIds))
                        {
                            depBundleIds = new HashSet<long>();
                            refBundlesMap.Add(dependency, depBundleIds);
                        }
                        depBundleIds.Add(bundleId);
                    }
                }
            }
            var sb = new System.Text.StringBuilder();
            sb.Append($"被引用的Addressable资源数量:{refBundlesMap.Count}\n");
            foreach (var item in refBundlesMap)
            {
                //sb.Clear();
                sb.Append($"Asset:{item.Key} 被{item.Value.Count}个Assetbundle引用。 BundleNames:");
                foreach (var bundleId in item.Value)
                {
                    sb.Append($" [{_context.bundleDataMap[bundleId].originBundleName}]");
                }
                sb.Append("\n");
                //Debug.Log(sb.ToString());
            }
            OutputText(sb.ToString());
        }
        private void OutputText(string text)
        {
            try
            {
                var path = Path.GetTempPath() + Path.GetRandomFileName();
                File.WriteAllText(path, text);
#if UNITY_EDITOR_WIN
                var proc = System.Diagnostics.Process.Start("notepad.exe", path);
#else
                Debug.Log($"Output:{path}");
#endif
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }

        }
    }
}
