using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace TapTapMiniGame
{
    /// <summary>
    /// 文件系统状态和错误管理
    /// </summary>
    public static class FileSystemStats
    {
        /// <summary>
        /// 文件系统错误码枚举
        /// </summary>
        public enum ErrorCode
        {
            OperationNotPermitted = 1300001,     // 操作不被允许
            NoSuchFileOrDirectory = 1300002,     // 文件/目录不存在
            InputOutputError = 1300005,          // 输入输出流不可用
            BadFileDescriptor = 1300009,         // 无效的文件描述符
            PermissionDenied = 1300013,          // 权限错误，文件是只读或只写
            PathPermissionDenied = 1300014,      // 传入的路径没有权限
            NotADirectory = 1300020,             // 指定路径不是目录
            IsADirectory = 1300021,              // 指定路径是一个目录
            InvalidArgument = 1300022,           // 无效参数
            FileNameTooLong = 1300036,           // 文件名过长
            DirectoryNotEmpty = 1300066,         // 目录不为空
            SystemError = 1300201,               // 系统接口调用失败
            StorageLimitExceeded = 1300202,      // 存储空间不足，或文件大小超出上限
            Base64EncodeError = 1300203,         // 字符编码转换失败
            SdCardNotMounted = 1300300,          // android sdcard 挂载失败
            UnableToOpenAsFileType = 1300301,    // 无法以fileType打开文件
            CannotAccessFilePath = 1301000,      // 目标路径无访问权限
            DataToWriteIsEmpty = 1301002,        // 写入数据为空
            IllegalOperationOnDirectory = 1301003, // 不可对目录进行此操作
            IllegalOperationOnPackageDir = 1301004, // 不可对代码包目录进行此操作
            FileAlreadyExists = 1301005,         // 已有同名文件或目录
            LengthOutOfRange = 1301006,          // 传入的 length 不合法
            OffsetOutOfRange = 1301007,          // 传入的 offset 不合法
            PositionOutOfRange = 1301009,        // position值越界
            StoreDirectoryEmpty = 1301100,       // store目录为空
            UnzipOpenFileFail = 1301102,         // 压缩文件打开失败
            UnzipEntryFail = 1301103,            // 解压单个文件失败
            UnzipFail = 1301104,                 // 解压失败
            BrotliDecompressFail = 1301111,      // brotli解压失败
            TempFilePathNotExist = 1301112,      // 指定的 tempFilePath 找不到文件
            PermissionDeniedForFD = 1302001,     // 指定的 fd 路径没有读权限/没有写权限
            ExceedMaxConcurrentFdLimit = 1302002, // fd数量已达上限
            InvalidFlag = 1302003,               // 无效的flag
            PermissionDeniedForFlag = 1302004,   // 无法使用flag标志打开文件
            ArrayBufferNotExist = 1302005,       // 未传入arrayBuffer
            ArrayBufferReadOnly = 1302100        // arrayBuffer只读
        }

        /// <summary>
        /// 错误码映射到错误描述
        /// </summary>
        private static readonly Dictionary<ErrorCode, string> ErrorDescriptions = 
            new Dictionary<ErrorCode, string>
            {
                { ErrorCode.OperationNotPermitted, "操作不被允许（例如，filePath 预期传入一个文件而实际传入一个目录）" },
                { ErrorCode.NoSuchFileOrDirectory, "文件/目录不存在，或者目标文件路径的上层目录不存在" },
                { ErrorCode.InputOutputError, "输入输出流不可用" },
                { ErrorCode.BadFileDescriptor, "无效的文件描述符" },
                { ErrorCode.PermissionDenied, "权限错误，文件是只读或只写" },
                { ErrorCode.PathPermissionDenied, "传入的路径没有权限" },
                { ErrorCode.NotADirectory, "dirPath 指定路径不是目录，常见于指定的写入路径的上级路径为一个文件的情况" },
                { ErrorCode.IsADirectory, "指定路径是一个目录" },
                { ErrorCode.InvalidArgument, "无效参数，可以检查length或offset是否越界" },
                { ErrorCode.FileNameTooLong, "文件名过长" },
                { ErrorCode.DirectoryNotEmpty, "目录不为空" },
                { ErrorCode.SystemError, "系统接口调用失败" },
                { ErrorCode.StorageLimitExceeded, "存储空间不足，或文件大小超出上限（上限100M）" },
                { ErrorCode.Base64EncodeError, "字符编码转换失败（例如 base64 格式错误）" },
                { ErrorCode.SdCardNotMounted, "android sdcard 挂载失败" },
                { ErrorCode.UnableToOpenAsFileType, "无法以fileType打开文件" },
                { ErrorCode.CannotAccessFilePath, "目标路径无访问权限（usr目录）" },
                { ErrorCode.DataToWriteIsEmpty, "写入数据为空" },
                { ErrorCode.IllegalOperationOnDirectory, "不可对目录进行此操作（例如，指定的 filePath 是一个已经存在的目录）" },
                { ErrorCode.IllegalOperationOnPackageDir, "不可对代码包目录进行此操作" },
                { ErrorCode.FileAlreadyExists, "已有同名文件或目录" },
                { ErrorCode.LengthOutOfRange, "传入的 length 不合法" },
                { ErrorCode.OffsetOutOfRange, "传入的 offset 不合法" },
                { ErrorCode.PositionOutOfRange, "position值越界" },
                { ErrorCode.StoreDirectoryEmpty, "store目录为空" },
                { ErrorCode.UnzipOpenFileFail, "压缩文件打开失败" },
                { ErrorCode.UnzipEntryFail, "解压单个文件失败" },
                { ErrorCode.UnzipFail, "解压失败" },
                { ErrorCode.BrotliDecompressFail, "brotli解压失败（例如，指定的 compressionAlgorithm 与文件实际压缩格式不符）" },
                { ErrorCode.TempFilePathNotExist, "指定的 tempFilePath 找不到文件" },
                { ErrorCode.PermissionDeniedForFD, "指定的 fd 路径没有读权限/没有写权限" },
                { ErrorCode.ExceedMaxConcurrentFdLimit, "fd数量已达上限" },
                { ErrorCode.InvalidFlag, "无效的flag" },
                { ErrorCode.PermissionDeniedForFlag, "无法使用flag标志打开文件" },
                { ErrorCode.ArrayBufferNotExist, "未传入arrayBuffer" },
                { ErrorCode.ArrayBufferReadOnly, "arrayBuffer只读" }
            };

        /// <summary>
        /// 获取错误描述
        /// </summary>
        /// <param name="errorCode">错误码枚举值</param>
        /// <returns>对应的错误描述</returns>
        public static string GetErrorDescription(ErrorCode errorCode)
        {
            if (ErrorDescriptions.TryGetValue(errorCode, out string description))
            {
                return description;
            }
            return "未定义的错误码: " + (int)errorCode;
        }

        /// <summary>
        /// 获取错误描述
        /// </summary>
        /// <param name="errorCode">错误码的整数值</param>
        /// <returns>对应的错误描述</returns>
        public static string GetErrorDescription(int errorCode)
        {
            if (Enum.IsDefined(typeof(ErrorCode), errorCode))
            {
                return GetErrorDescription((ErrorCode)errorCode);
            }
            return "未定义的错误码: " + errorCode;
        }

        /// <summary>
        /// 从错误信息字符串中解析错误码
        /// </summary>
        /// <param name="errorMessage">错误信息字符串</param>
        /// <returns>解析出的错误码，如果未找到则返回0</returns>
        public static int ParseErrorCode(string errorMessage)
        {
            if (string.IsNullOrEmpty(errorMessage))
                return 0;
                
            if (TryGetFileSystemErrorCode(errorMessage, out int code) && 
                Enum.IsDefined(typeof(ErrorCode), code))
            {
                return code;
            }
            
            return 0;
        }

        /// <summary>
        /// 检查文件系统操作返回值是否包含错误码
        /// </summary>
        /// <param name="result">文件系统操作的返回值</param>
        /// <returns>如果包含错误false</returns>
        public static bool CheckFileSystemError(string result)
        {
            if (string.IsNullOrEmpty(result))
                return false;
            
            // 检查是否包含特定错误字符串，如果包含则视为非错误
            if (result.Contains("fail") || result.Contains("permission denied"))
                return false;
            
            // 检查是否包含130开头的错误码
            return !Regex.IsMatch(result, @"130\d{4}");
        }

        /// <summary>
        /// 从文件系统操作结果中提取错误码
        /// </summary>
        /// <param name="result">文件系统操作结果</param>
        /// <param name="errorCode">输出的错误码</param>
        /// <returns>如果包含错误码返回true，否则返回false</returns>
        public static bool TryGetFileSystemErrorCode(string result, out int errorCode)
        {
            errorCode = 0;
            
            if (string.IsNullOrEmpty(result))
                return false;
            
            var match = Regex.Match(result, @"130\d{4}");
            if (match.Success)
            {
                return int.TryParse(match.Value, out errorCode);
            }
            
            return false;
        }
    }
} 