//! Error types for tmux-fzf operations.
//!
//! This module defines the main error type [`TmuxFzfError`] which covers all
//! possible error conditions that can occur during tmux session management.

use std::fmt;

/// Main error type for tmux-fzf operations.
///
/// This enum covers all possible error conditions that can occur
/// during tmux session management and user interactions.
#[derive(Debug)]
#[allow(dead_code)]
pub enum TmuxFzfError {
    /// A required dependency (like tmux) is not installed
    DependencyMissing(String),
    /// An error occurred when executing a tmux command
    TmuxError(String),
    /// An error occurred in the fuzzy finder interface
    FzfError(String),
    /// An I/O error occurred (file system, terminal, etc.)
    IoError(std::io::Error),
    /// No tmux sessions were found
    NoSessions,
    /// The user cancelled the operation
    UserCancelled,
    /// An invalid session name was provided
    InvalidSessionName(String),
}

impl fmt::Display for TmuxFzfError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            TmuxFzfError::DependencyMissing(dep) => {
                write!(f, "{} is not installed", dep)
            }
            TmuxFzfError::TmuxError(msg) => {
                write!(f, "tmux error: {}", msg)
            }
            TmuxFzfError::FzfError(msg) => {
                write!(f, "fzf error: {}", msg)
            }
            TmuxFzfError::IoError(err) => {
                write!(f, "IO error: {}", err)
            }
            TmuxFzfError::NoSessions => {
                write!(f, "no tmux sessions found")
            }
            TmuxFzfError::UserCancelled => {
                write!(f, "operation cancelled by user")
            }
            TmuxFzfError::InvalidSessionName(name) => {
                write!(f, "invalid session name: {}", name)
            }
        }
    }
}

impl std::error::Error for TmuxFzfError {}

impl From<std::io::Error> for TmuxFzfError {
    fn from(err: std::io::Error) -> Self {
        TmuxFzfError::IoError(err)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::io;

    #[test]
    fn test_error_display() {
        let error = TmuxFzfError::DependencyMissing("tmux".to_string());
        assert_eq!(format!("{}", error), "tmux is not installed");

        let error = TmuxFzfError::TmuxError("command failed".to_string());
        assert_eq!(format!("{}", error), "tmux error: command failed");

        let error = TmuxFzfError::FzfError("selection failed".to_string());
        assert_eq!(format!("{}", error), "fzf error: selection failed");

        let error = TmuxFzfError::NoSessions;
        assert_eq!(format!("{}", error), "no tmux sessions found");

        let error = TmuxFzfError::UserCancelled;
        assert_eq!(format!("{}", error), "operation cancelled by user");

        let error = TmuxFzfError::InvalidSessionName("bad:name".to_string());
        assert_eq!(format!("{}", error), "invalid session name: bad:name");
    }

    #[test]
    fn test_error_from_io_error() {
        let io_error = io::Error::new(io::ErrorKind::PermissionDenied, "permission denied");
        let tmux_error: TmuxFzfError = io_error.into();
        
        match tmux_error {
            TmuxFzfError::IoError(err) => {
                assert_eq!(err.kind(), io::ErrorKind::PermissionDenied);
                assert_eq!(err.to_string(), "permission denied");
            }
            _ => panic!("Expected IoError variant"),
        }
    }

    #[test]
    fn test_error_is_error_trait() {
        let error = TmuxFzfError::NoSessions;
        let _: &dyn std::error::Error = &error;
    }
}