// 导入依赖项
use std::path::PathBuf;
use thiserror::Error; // 用于自动实现 Error trait 的宏 // 路径类型

/// 应用程序的 Result 类型别名
///
/// 这是一个便利类型，将标准库的 Result 类型固定为使用 LsPlusError 作为错误类型。
/// 在整个应用程序中使用这个类型别名来简化函数签名。
pub type Result<T> = std::result::Result<T, LsPlusError>;

/// ls-plus 应用程序的错误类型枚举
///
/// 定义了应用程序中可能出现的所有错误类型。使用 thiserror crate
/// 来自动实现 Error trait 和格式化功能。
///
/// 每个错误变体都包含相关的上下文信息，以便提供有用的错误信息给用户。
#[derive(Error, Debug)]
pub enum LsPlusError {
    /// I/O 操作错误
    ///
    /// 当文件系统操作失败时抛出，例如文件读取、写入或访问权限问题。
    /// 这个变体会自动从 std::io::Error 转换而来。
    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),

    /// 路径不存在错误
    ///
    /// 当尝试访问一个不存在的文件或目录时抛出。
    #[error("Path not found: {path}")]
    PathNotFound { path: PathBuf },

    /// 权限被拒绝错误
    ///
    /// 当没有足够权限访问文件或目录时抛出。
    #[error("Permission denied: {path}")]
    PermissionDenied { path: PathBuf },

    /// 配置无效错误
    ///
    /// 当配置文件内容格式错误或包含无效值时抛出。
    #[error("Invalid configuration: {message}")]
    InvalidConfig { message: String },

    /// 配置文件格式错误
    ///
    /// 当 TOML 配置文件解析失败时抛出。
    /// 这个变体会自动从 toml::de::Error 转换而来。
    #[error("Configuration file error: {0}")]
    ConfigFile(#[from] toml::de::Error),

    /// JSON 序列化错误
    ///
    /// 当 JSON 输出格式化失败时抛出。
    /// 这个变体会自动从 serde_json::Error 转换而来。
    #[error("JSON serialization error: {0}")]
    JsonSerialization(#[from] serde_json::Error),

    /// Git 操作错误
    ///
    /// 当 Git 相关操作失败时抛出，例如获取仓库状态或分支信息失败。
    #[error("Git error: {message}")]
    Git { message: String },

    /// 模式匹配错误
    ///
    /// 当文件搜索的模式无效或匹配失败时抛出。
    #[error("Pattern matching error: {pattern}")]
    PatternError { pattern: String },

    /// 格式化错误
    ///
    /// 当输出格式化或数据转换失败时抛出。
    #[error("Format error: {message}")]
    Format { message: String },

    /// 系统级错误
    ///
    /// 通用的系统级错误，用于其他未分类的错误情况。
    #[error("System error: {message}")]
    System { message: String },
}

/// LsPlusError 的便利构造方法
///
/// 提供了一系列的静态方法来方便地分裁和创建具体的错误实例。
impl LsPlusError {
    /// 创建路径不存在错误
    ///
    /// # 参数
    /// * `path` - 不存在的路径
    ///
    /// # 返回值
    /// * `Self` - PathNotFound 错误实例
    pub fn path_not_found(path: PathBuf) -> Self {
        Self::PathNotFound { path }
    }

    /// 创建权限被拒绝错误
    ///
    /// # 参数
    /// * `path` - 被拒绝访问的路径
    ///
    /// # 返回值
    /// * `Self` - PermissionDenied 错误实例
    pub fn permission_denied(path: PathBuf) -> Self {
        Self::PermissionDenied { path }
    }

    /// 创建配置无效错误
    ///
    /// # 参数
    /// * `message` - 错误消息，可以是任何可转换为 String 的类型
    ///
    /// # 返回值
    /// * `Self` - InvalidConfig 错误实例
    pub fn invalid_config<S: Into<String>>(message: S) -> Self {
        Self::InvalidConfig {
            message: message.into(),
        }
    }

    /// 创建 Git 操作错误
    ///
    /// # 参数
    /// * `message` - 错误消息，可以是任何可转换为 String 的类型
    ///
    /// # 返回值
    /// * `Self` - Git 错误实例
    pub fn git_error<S: Into<String>>(message: S) -> Self {
        Self::Git {
            message: message.into(),
        }
    }

    /// 创建模式匹配错误
    ///
    /// # 参数
    /// * `pattern` - 导致错误的模式字符串
    ///
    /// # 返回值
    /// * `Self` - PatternError 错误实例
    pub fn pattern_error<S: Into<String>>(pattern: S) -> Self {
        Self::PatternError {
            pattern: pattern.into(),
        }
    }

    /// 创建格式化错误
    ///
    /// # 参数
    /// * `message` - 错误消息，可以是任何可转换为 String 的类型
    ///
    /// # 返回值
    /// * `Self` - Format 错误实例
    pub fn format_error<S: Into<String>>(message: S) -> Self {
        Self::Format {
            message: message.into(),
        }
    }

    /// 创建系统级错误
    ///
    /// # 参数
    /// * `message` - 错误消息，可以是任何可转换为 String 的类型
    ///
    /// # 返回值
    /// * `Self` - System 错误实例
    pub fn system_error<S: Into<String>>(message: S) -> Self {
        Self::System {
            message: message.into(),
        }
    }
}
