using System.Collections.Generic;
using System.IO;
using XGame.Editor.Asset;

namespace XGame.Editor.Build
{
    static class AssetUtils
    {
        /// <summary>
        /// 海报资源标签
        /// </summary>
        public const string PlacardTag = "/placard/";

        /// <summary>
        /// 内置资源标签（必须保留在安装包内部）
        /// </summary>
        public static string[] InnerAssetsTags => new string[] { "/XGame/", "/launch/", PlacardTag };

        /// <summary>
        /// 忽略文件
        /// </summary>
        public static string[] IgnoreFiles = new string[] { ".manifest", ".pdb", ".gitkeep", "buildlogtep.json" };

        /// <summary>
        /// 判断一个资源是否为内置资源
        /// </summary>
        /// <param name="assetPath">资源路径</param>
        /// <param name="innerAssetsTags">内置资源标签，为空使用默认值</param>
        /// <returns></returns>
        public static bool IsInnerAsset(string assetPath, params string[] innerAssetsTags)
        {
            if (null == innerAssetsTags) innerAssetsTags = InnerAssetsTags;

            assetPath = assetPath.ToLower();
            foreach (var tag in innerAssetsTags)
            {
                if (!assetPath.Contains(tag)) continue;
                return true;
            }
            return false;
        }

        /// <summary>
        /// 判断资源文件是否为忽略文件
        /// </summary>
        /// <param name="path"></param>
        /// <param name="ignorFiles"></param>
        /// <returns></returns>
        public static bool IsIgnorFile(string path, string[] ignorFiles = null)
        {
            var ext = Path.GetExtension(path);
            if (string.IsNullOrEmpty(ext))
            {
                //文件没有后缀
                BuildLog.Warn($"[CmdSubPackage] [BuildHelperControl] Unknown file extensions. Path: {path}");
                return true;
            }

            if (null == ignorFiles) ignorFiles = IgnoreFiles;
            foreach (var ignor in ignorFiles)
            {
                if (path.EndsWith(ignor, System.StringComparison.OrdinalIgnoreCase))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 获取相对路径
        /// </summary>
        /// <param name="absolutePath">绝对路径</param>
        /// <param name="relativeDir">相对目录</param>
        /// <returns></returns>
        public static string GetRelativePath(string absolutePath, string relativeDir = null)
        {
            if (string.IsNullOrEmpty(absolutePath))
                return absolutePath;
            absolutePath = absolutePath.Replace('\\', '/');

            if (string.IsNullOrEmpty(relativeDir)) relativeDir = Framework.Define.PathDefine.WorkPath;
            relativeDir = relativeDir.Replace('\\', '/');

            int index = absolutePath.LastIndexOf(relativeDir);
            if (index < 0)
                return absolutePath;

            if (relativeDir.EndsWith("/"))
                return absolutePath.Substring(index + relativeDir.Length);

            return absolutePath.Substring(index + relativeDir.Length + 1);
        }

        ///// <summary>
        ///// 获取二进制文件的校验码
        ///// </summary>
        ///// <param name="filePath">文件路径</param>
        ///// <param name="checkCodeType">校验码类型</param>
        ///// <returns></returns>
        //public static string GetBinaryCheckCode(string filePath, ECheckCodeType checkCodeType)
        //{
        //    string result;
        //    switch (checkCodeType)
        //    {
        //        case ECheckCodeType.MD5:
        //        default:
        //            result = KailashNative.GetMD5(filePath);
        //            break;
        //    }
        //    if (string.IsNullOrEmpty(result))
        //        BuildLog.Error("[CmdSubPackage] [BuildHelperControl] GetFileCheckCode find invalid {0}, file path is {1}.", checkCodeType, filePath);
        //    return result;
        //}

        #region collect assets

        /// <summary>
        /// 收集所有资源信息
        /// </summary>
        /// <returns></returns>
        public static Dictionary<string, string> CollectionAllAssets()
        {
            Dictionary<string, string> assets = new Dictionary<string, string>();
            var platformNames = System.Enum.GetNames(typeof(Framework.PlatformType));
            CollectionAssetsInternal(Framework.Define.PathDefine.WorkPath, 0, ref assets);
            return assets;
        }

        private static void CollectionAssetsInternal(string root, int platformTag, ref Dictionary<string, string> assets)
        {
            string[] directories = Directory.GetDirectories(root);
            foreach (var dir in directories)
            {
                var subPlatformTag = platformTag;
                var dirPath = dir.Replace("\\", "/");

                if (subPlatformTag != 1)
                    subPlatformTag = FileUtil.VerifyPlatformPath(dirPath);
                if (subPlatformTag == -1)
                    continue;

                CollectionAssetsInternal(dirPath, subPlatformTag, ref assets);
            }

            string[] files = Directory.GetFiles(root);
            foreach (var file in files)
            {
                var filePath = file.Replace("\\", "/");
                if (IsIgnorFile(filePath)) continue;
                string relativePath = GetRelativePath(filePath);
                if (platformTag == 1)
                {
                    relativePath = relativePath.Replace(PlatformUtil.ActivePlatform.ToString() + '/', string.Empty);
                }
                assets.Add(filePath, relativePath);
            }
        }

        #endregion
    }
}
