﻿using System;
using System.Collections.Generic;
using System.IO;
using JLGames.RocketDriver.CSharp.Utils;
using UnityEditor;
using UnityEngine;

namespace JLGames.RocketDriver.Editor.Infra
{
    public static class BuildBundleUtil
    {
        private static readonly List<string> ForbitNames = new List<string>();

        static BuildBundleUtil()
        {
            ForbitNames.Add("");
            ForbitNames.Add("temp");
            ForbitNames.Add("tmp");
        }

        public static bool CheckForbit(string name, bool mathCase = false)
        {
            var cn = mathCase ? name : name.ToLower();
            return ForbitNames.Contains(cn);
        }

        public static void BuildAssetBundles(BuildBundleConfig.TargetInfo target)
        {
            BuildProjectUtil.PreparePlaform(target.BuildTargetGroup, target.BuildTarget);
            AssetDatabase.Refresh();
            var path = target.BuildOutPath;
            var startLog = $"Start Build Bundles({target.BuildOutDir}) At {DateTime.UtcNow.ToLocalTime()}";
            Debug.Log(startLog);
            if (Directory.Exists(path))
            {
                DirectoryUtil.ClearDir(path, true);
            }
            else
            {
                DirectoryUtil.MakeDir(path);
            }

            BuildPipeline.BuildAssetBundles(path, target.Options, target.BuildTarget);
            var finishLog = $"Finish Build Bundles({target.BuildOutDir}) At {DateTime.UtcNow.ToLocalTime()}";
            Debug.Log(finishLog);
        }

        public static bool CheckAssetBundlesEmpty()
        {
            var bundleNames = AssetDatabase.GetAllAssetBundleNames();
            if (0 == bundleNames.Length)
            {
                Debug.Log("No Bundles!");
                return true;
            }

            return false;
        }

        public static void CheckBundleNameForbit()
        {
            var bundleNames = AssetDatabase.GetAllAssetBundleNames();
            if (0 == bundleNames.Length)
            {
                Debug.Log("No Bundles!");
                return;
            }

            var has = false;
            foreach (var bundleName in bundleNames)
            {
                if (CheckForbit(bundleName.ToLower()))
                {
                    has = true;
                    Debug.LogWarning($"Forbit Name={bundleName}");
                }
            }

            if (!has)
            {
                Debug.Log($"No Forbit Names. Bundles list=[{string.Join(",", bundleNames)}]");
            }
        }

        public static void CheckAbAssetDuplicate(bool mathCase)
        {
            var bundleNames = AssetDatabase.GetAllAssetBundleNames();
            if (0 == bundleNames.Length)
            {
                return;
            }

            var has = false;
            foreach (var bundleName in bundleNames)
            {
                var assets = AssetDatabase.GetAssetPathsFromAssetBundle(bundleName);
                var map = new Dictionary<string, List<string>>();
                foreach (var name in assets)
                {
                    var fName = Path.GetFileNameWithoutExtension(name);
                    if (string.IsNullOrEmpty(fName))
                    {
                        Debug.LogWarning($"Bundle({bundleName}) Warning: Empty name of asset. ");
                        continue;
                    }

                    fName = mathCase ? fName : fName.ToLower();
                    if (!map.ContainsKey(fName))
                    {
                        map[fName] = new List<string>();
                    }

                    map[fName].Add(name);
                }

                foreach (var item in map)
                {
                    if (item.Value.Count <= 1)
                    {
                        continue;
                    }

                    has = true;
                    foreach (var path in item.Value)
                    {
                        Debug.LogWarning($"Duplicate Asset Info: {item.Key}:{path}");
                    }
                }
            }

            if (!has)
            {
                Debug.Log("No Duplicate Asset Names. ");
            }
        }
    }
}