//! Toggles the swap parity of the GCD state.

use super::GcdState;

impl GcdState {
    /// Flips the cumulative swap parity.
    ///
    /// Each Euclidean reduction step (full-precision, scalar, or Lehmer matrix
    /// application) swaps the roles of `r0`/`r1` and `t0`/`t1`. This method
    /// records that swap by toggling `even`, which determines the sign
    /// correction applied when extracting the final inverse.
    ///
    /// # Examples
    ///
    /// ```
    /// use cnfy_uint::gcd_state::GcdState;
    /// use cnfy_uint::u256::U256;
    ///
    /// let mut state = GcdState::new(
    ///     U256::from_be_limbs([0, 0, 0, 97]),
    ///     U256::from_be_limbs([0, 0, 0, 42]),
    /// );
    /// assert!(state.even);
    /// state.toggle_even();
    /// assert!(!state.even);
    /// ```
    #[inline]
    pub fn toggle_even(&mut self) {
        self.even = !self.even;
    }
}

#[cfg(test)]
mod ai_tests {
    use crate::u256::U256;

    use super::*;

    /// Toggling once flips from true to false.
    #[test]
    fn toggle_once() {
        let mut state = GcdState::new(
            U256::from_be_limbs([0, 0, 0, 97]),
            U256::from_be_limbs([0, 0, 0, 42]),
        );
        assert!(state.even);
        state.toggle_even();
        assert!(!state.even);
    }

    /// Toggling twice restores original parity.
    #[test]
    fn toggle_twice_restores() {
        let mut state = GcdState::new(
            U256::from_be_limbs([0, 0, 0, 97]),
            U256::from_be_limbs([0, 0, 0, 42]),
        );
        state.toggle_even();
        state.toggle_even();
        assert!(state.even);
    }

    /// Toggling from false goes to true.
    #[test]
    fn toggle_from_false() {
        let mut state = GcdState {
            modulus: U256::ZERO,
            r0: U256::ZERO,
            r1: U256::ZERO,
            t0: U256::ZERO,
            t1: U256::ZERO,
            even: false,
        };
        state.toggle_even();
        assert!(state.even);
    }
}
