use std::fmt;

use async_trait::async_trait;

use super::topology::IpAddress;

#[derive(Debug)]
pub enum ExecutorError {
    NetworkError(String),
    AuthenticationError(String),
    ConfigurationError(String),
    UnexpectedError(String),
}

impl fmt::Display for ExecutorError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            ExecutorError::NetworkError(msg) => write!(f, "Network error: {}", msg),
            ExecutorError::AuthenticationError(msg) => write!(f, "Authentication error: {}", msg),
            ExecutorError::ConfigurationError(msg) => write!(f, "Configuration error: {}", msg),
            ExecutorError::UnexpectedError(msg) => write!(f, "Unexpected error: {}", msg),
        }
    }
}

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

#[async_trait]
pub trait SshClient {
    async fn test_connection(
        &self,
        address: IpAddress,
        username: &str,
        password: &str,
    ) -> Result<(), ExecutorError>;
}
