//! Integer division via the [`Div`] trait.

use super::U256;
use core::ops::Div;

/// Integer division of two 256-bit unsigned integers.
///
/// Returns `floor(self / rhs)`, discarding the remainder. Delegates to
/// [`U256::div_rem`] and returns only the quotient.
///
/// # Panics
///
/// Loops indefinitely if `rhs` is zero.
///
/// # Examples
///
/// ```
/// use cnfy_uint::u256::U256;
///
/// let a = U256::from_be_limbs([0, 0, 0, 10]);
/// let b = U256::from_be_limbs([0, 0, 0, 3]);
/// assert_eq!(a / b, U256::from_be_limbs([0, 0, 0, 3]));
/// ```
impl Div for U256 {
    type Output = U256;

    #[inline]
    fn div(self, rhs: U256) -> U256 {
        self.div_rem(&rhs).0
    }
}

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

    /// 10 / 3 = 3.
    #[test]
    fn ten_div_three() {
        let a = U256::from_be_limbs([0, 0, 0, 10]);
        let b = U256::from_be_limbs([0, 0, 0, 3]);
        assert_eq!(a / b, U256::from_be_limbs([0, 0, 0, 3]));
    }

    /// 8 / 2 = 4.
    #[test]
    fn eight_div_two() {
        let a = U256::from_be_limbs([0, 0, 0, 8]);
        let b = U256::from_be_limbs([0, 0, 0, 2]);
        assert_eq!(a / b, U256::from_be_limbs([0, 0, 0, 4]));
    }

    /// Division by one is identity.
    #[test]
    fn div_by_one() {
        let a = U256::from_be_limbs([0x1234, 0x5678, 0x9ABC, 0xDEF0]);
        assert_eq!(a / U256::ONE, a);
    }

    /// Self-division yields one.
    #[test]
    fn self_division() {
        let a = U256::from_be_limbs([0x1234, 0x5678, 0x9ABC, 0xDEF0]);
        assert_eq!(a / a, U256::ONE);
    }

    /// Dividend smaller than divisor yields zero.
    #[test]
    fn smaller_dividend() {
        let a = U256::from_be_limbs([0, 0, 0, 3]);
        let b = U256::from_be_limbs([0, 0, 0, 10]);
        assert_eq!(a / b, U256::ZERO);
    }

    /// Large values: MAX / 2.
    #[test]
    fn max_div_two() {
        let two = U256::from_be_limbs([0, 0, 0, 2]);
        assert_eq!(
            U256::MAX / two,
            U256::from_be_limbs([
                0x7FFFFFFFFFFFFFFF,
                0xFFFFFFFFFFFFFFFF,
                0xFFFFFFFFFFFFFFFF,
                0xFFFFFFFFFFFFFFFF,
            ]),
        );
    }
}
