use thiserror::Error;

#[derive(Error, Debug)]
pub enum PrehookError {
    #[error("Hook error: {0}")]
    Hook(String),

    #[error("Target not found: {0}")]
    TargetNotFound(String),

    #[error("Symbol not found: {0}")]
    SymbolNotFound(String),

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

impl From<ilhook::HookError> for PrehookError {
    fn from(e: ilhook::HookError) -> Self {
        PrehookError::Hook(e.to_string())
    }
}

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

    #[test]
    fn test_error_display() {
        let err = PrehookError::Hook("test error".to_string());
        assert_eq!(err.to_string(), "Hook error: test error");

        let err = PrehookError::TargetNotFound("binary not found".to_string());
        assert_eq!(err.to_string(), "Target not found: binary not found");

        let err = PrehookError::SymbolNotFound("mysym".to_string());
        assert_eq!(err.to_string(), "Symbol not found: mysym");

        let err = PrehookError::Init("init failed".to_string());
        assert_eq!(err.to_string(), "Initialization error: init failed");
    }

    #[test]
    fn test_error_from_ilhook() {
        let ilhook_err = ilhook::HookError::Unknown;
        let err: PrehookError = ilhook_err.into();
        assert!(matches!(err, PrehookError::Hook(_)));
    }
}
