//! Platform detection utilities for identifying the operating system and architecture.
//!
//! This module provides functions to detect the current platform at runtime,
//! including OS type (macOS, Linux) and CPU architecture (x86_64, ARM).

use thiserror::Error;

/// Errors returned by platform checking operations.
#[derive(Debug, Error)]
pub enum PlatformError {
    /// A generic platform error with a kind and descriptive message.
    #[error("{0}: {1}")]
    Generic(String, String),
}

impl PlatformError {
    /// Creates a new platform error.
    ///
    /// # Arguments
    ///
    /// * `kind` - The error kind/category
    /// * `message` - The error message
    ///
    /// # Example
    ///
    /// ```no_run
    /// use herolib_os::os::PlatformError;
    ///
    /// let err = PlatformError::new("Unsupported", "Feature not available on this platform");
    /// ```
    pub fn new(kind: &str, message: &str) -> Self {
        PlatformError::Generic(kind.to_string(), message.to_string())
    }
}

/// Checks if the current platform is macOS.
///
/// Returns `true` if running on macOS, `false` otherwise.
///
/// # Example
///
/// ```no_run
/// use herolib_os::os::is_osx;
///
/// if is_osx() {
///     println!("Running on macOS");
/// }
/// ```
#[cfg(target_os = "macos")]
pub fn is_osx() -> bool {
    true
}

/// Checks if the current platform is macOS.
///
/// Returns `true` if running on macOS, `false` otherwise.
#[cfg(not(target_os = "macos"))]
pub fn is_osx() -> bool {
    false
}

/// Checks if the current platform is Linux.
///
/// Returns `true` if running on Linux, `false` otherwise.
///
/// # Example
///
/// ```no_run
/// use herolib_os::os::is_linux;
///
/// if is_linux() {
///     println!("Running on Linux");
/// }
/// ```
#[cfg(target_os = "linux")]
pub fn is_linux() -> bool {
    true
}

/// Checks if the current platform is Linux.
///
/// Returns `true` if running on Linux, `false` otherwise.
#[cfg(not(target_os = "linux"))]
pub fn is_linux() -> bool {
    false
}

/// Checks if the current CPU architecture is ARM (aarch64).
///
/// Returns `true` if running on ARM64/aarch64 architecture, `false` otherwise.
///
/// # Example
///
/// ```no_run
/// use herolib_os::os::is_arm;
///
/// if is_arm() {
///     println!("Running on ARM64");
/// }
/// ```
#[cfg(target_arch = "aarch64")]
pub fn is_arm() -> bool {
    true
}

/// Checks if the current CPU architecture is ARM (aarch64).
///
/// Returns `true` if running on ARM64/aarch64 architecture, `false` otherwise.
#[cfg(not(target_arch = "aarch64"))]
pub fn is_arm() -> bool {
    false
}

/// Checks if the current CPU architecture is x86_64.
///
/// Returns `true` if running on x86_64 architecture, `false` otherwise.
///
/// # Example
///
/// ```no_run
/// use herolib_os::os::is_x86;
///
/// if is_x86() {
///     println!("Running on x86_64");
/// }
/// ```
#[cfg(target_arch = "x86_64")]
pub fn is_x86() -> bool {
    true
}

/// Checks if the current CPU architecture is x86_64.
///
/// Returns `true` if running on x86_64 architecture, `false` otherwise.
#[cfg(not(target_arch = "x86_64"))]
pub fn is_x86() -> bool {
    false
}

/// Verifies the platform is Linux on x86_64 architecture.
///
/// Returns `Ok(())` if the platform is Linux x86_64, otherwise returns an error.
///
/// # Errors
///
/// Returns a `PlatformError` if the platform is not Linux x86_64.
///
/// # Example
///
/// ```no_run
/// use herolib_os::os::check_linux_x86;
///
/// match check_linux_x86() {
///     Ok(_) => println!("Platform is Linux x86_64"),
///     Err(e) => println!("Platform check failed: {}", e),
/// }
/// ```
pub fn check_linux_x86() -> Result<(), PlatformError> {
    if is_linux() && is_x86() {
        Ok(())
    } else {
        Err(PlatformError::new(
            "Platform Check Error",
            "This operation is only supported on Linux x86_64.",
        ))
    }
}

/// Verifies the platform is macOS on ARM (aarch64) architecture.
///
/// Returns `Ok(())` if the platform is macOS ARM, otherwise returns an error.
///
/// # Errors
///
/// Returns a `PlatformError` if the platform is not macOS ARM.
///
/// # Example
///
/// ```no_run
/// use herolib_os::os::check_macos_arm;
///
/// match check_macos_arm() {
///     Ok(_) => println!("Platform is macOS ARM"),
///     Err(e) => println!("Platform check failed: {}", e),
/// }
/// ```
pub fn check_macos_arm() -> Result<(), PlatformError> {
    if is_osx() && is_arm() {
        Ok(())
    } else {
        Err(PlatformError::new(
            "Platform Check Error",
            "This operation is only supported on macOS ARM.",
        ))
    }
}
