//! Full divstep execution loop for [`Divstep`].
use super::Divstep;

impl Divstep {
    /// Runs 12 macroiterations (12 × 62 = 744 divsteps, ≥ 724 needed for
    /// 256-bit moduli) to completion.
    ///
    /// After this, `g = 0` and `|f| = 1` for coprime inputs. The Bézout
    /// coefficient `d` (sign-corrected by the sign of `f`) is the modular
    /// inverse.
    pub(crate) fn run(mut self) -> Divstep {
        for _ in 0..12 {
            self.macrostep();
        }
        self
    }
}

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

    const P: U256 = U256::from_be_limbs([
        0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
        0xFFFFFFFFFFFFFFFF, 0xFFFFFFFEFFFFFC2F,
    ]);

    /// After run(), g should be zero for coprime inputs.
    #[test]
    fn g_is_zero_after_run() {
        let ds = Divstep::new(P, U256::from_be_limbs([0, 0, 0, 7])).run();
        assert!(ds.g.is_zero(), "g should be zero after 12 macrosteps, got {:?}", ds.g);
    }

    /// After run(), |f| should be 1 (the GCD).
    #[test]
    fn f_is_one_after_run() {
        let ds = Divstep::new(P, U256::from_be_limbs([0, 0, 0, 7])).run();
        assert_eq!(ds.f, U256::ONE, "f magnitude should be 1 after run");
    }
}
