#[derive(Debug, thiserror::Error)]
pub enum PortKillerError {
    #[error("invalid port: {0}. Port must be between 1 and 65535.")]
    InvalidPort(u16),

    #[error("{0}")]
    InvalidArguments(String),

    #[allow(dead_code)]
    #[error("unsupported platform: {0}.")]
    UnsupportedPlatform(String),

    #[error("required command not found: {0}.")]
    CommandNotFound(String),

    #[error("failed to run {command}: {source}")]
    CommandIo {
        command: String,
        source: std::io::Error,
    },

    #[error("failed to kill process {pid}: {reason}")]
    KillFailed { pid: u32, reason: String },

    #[error("failed to kill process {pid}: permission denied.")]
    PermissionDenied { pid: u32 },

    #[error("failed to write JSON: {0}")]
    Json(#[from] serde_json::Error),

    #[error("I/O error: {0}")]
    Io(#[from] std::io::Error),
}

impl PortKillerError {
    pub fn exit_code(&self) -> i32 {
        match self {
            Self::InvalidPort(_) | Self::InvalidArguments(_) => 2,
            Self::UnsupportedPlatform(_) => 4,
            Self::PermissionDenied { .. } => 5,
            Self::KillFailed { .. } => 3,
            Self::CommandNotFound(_) | Self::CommandIo { .. } | Self::Json(_) | Self::Io(_) => 1,
        }
    }
}
