#[cfg(feature = "blas-src")]
#[allow(unused_extern_crates)]
extern crate blas_src;
#[cfg(feature = "openblas-src")]
#[allow(unused_extern_crates)]
extern crate openblas_src;
#[cfg(feature = "netlib-src")]
#[allow(unused_extern_crates)]
extern crate netlib_src;
#[cfg(all(target_os = "macos", feature = "accelerate-src"))]
#[allow(unused_extern_crates)]
extern crate accelerate_src;

/// Implements Krippendorff's alpha for inter-rater reliability.
pub mod alpha;
/// Implements the Bradley–Terry model and related methods.
pub mod bradley_terry;
/// Implements counting-based rating methods.
pub mod counting;
/// Implements the Elo rating system.
pub mod elo;
/// Implements linear algebra-based rating methods.
pub mod linalg;
#[cfg(feature = "python")]
mod python;
/// Contains utility functions and macros.
pub mod utils;
#[cfg(feature = "wasm")]
pub mod wasm;

/// Returns whether BLAS support is enabled.
#[must_use]
pub const fn has_blas() -> bool {
    cfg!(feature = "blas")
}

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

    #[test]
    fn test_has_blas() {
        let result = has_blas();

        #[cfg(feature = "blas")]
        assert!(result, "BLAS should be available when feature is enabled");

        #[cfg(not(feature = "blas"))]
        assert!(
            !result,
            "BLAS should not be available when feature is disabled"
        );
    }
}

/// The outcome of the pairwise comparison.
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Winner {
    /// There is a tie.
    Draw = 0,
    /// The first element won.
    X = 1,
    /// The second element won.
    Y = 2,
}

impl TryFrom<u8> for Winner {
    type Error = &'static str;

    fn try_from(value: u8) -> Result<Self, Self::Error> {
        match value {
            0 => Ok(Self::Draw),
            1 => Ok(Self::X),
            2 => Ok(Self::Y),
            _ => Err("invalid winner value"),
        }
    }
}

impl From<Winner> for u8 {
    fn from(val: Winner) -> Self {
        match val {
            Winner::Draw => 0,
            Winner::X => 1,
            Winner::Y => 2,
        }
    }
}
