use std::io;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum CloudHypervisorError {
    #[error("IO error: {0}")]
    Io(#[from] io::Error),

    #[error("API error: {0}")]
    Api(String),

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

    #[error("Configuration error: {0}")]
    Config(String),

    #[error("VM not found: {0}")]
    VmNotFound(String),

    #[error("VM already exists: {0}")]
    VmAlreadyExists(String),

    #[error("Invalid state: {0}")]
    InvalidState(String),

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

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

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

    #[error("HTTP request failed: {0}")]
    Http(String),

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

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

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

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

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

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

    #[error("Feature not supported: {feature} - {reason}")]
    NotSupported { feature: String, reason: String },
}

// Implement From for hyper::Error
impl From<hyper::Error> for CloudHypervisorError {
    fn from(err: hyper::Error) -> Self {
        CloudHypervisorError::Hyper(err.to_string())
    }
}

// Implement From for which::Error  
impl From<which::Error> for CloudHypervisorError {
    fn from(err: which::Error) -> Self {
        CloudHypervisorError::Which(err.to_string())
    }
}

pub type Result<T> = std::result::Result<T, CloudHypervisorError>;
