//! SGP4 vs SDP4 selection based on orbital period.

use crate::tle::newtypes::MeanMotion;

/// Propagator variant selected by orbital period.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PropagatorKind {
    /// Near-earth: orbital period < 225 minutes.
    Sgp4,
    /// Deep-space: orbital period >= 225 minutes.
    Sdp4,
}

/// Select the appropriate propagator based on mean motion.
///
/// Satellites with orbital period < 225 minutes use SGP4 (near-earth);
/// those with period >= 225 minutes use SDP4 (deep-space with
/// luni-solar perturbations).
#[must_use]
pub fn select_propagator(mean_motion: MeanMotion) -> PropagatorKind {
    if mean_motion.period_minutes() < 225.0 {
        PropagatorKind::Sgp4
    } else {
        PropagatorKind::Sdp4
    }
}

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

    #[test]
    fn iss_is_near_earth() -> Result<(), Error> {
        // ISS: ~15.5 rev/day => period ~92.9 min
        let mm = MeanMotion::new(15.5)?;
        assert_eq!(select_propagator(mm), PropagatorKind::Sgp4);
        Ok(())
    }

    #[test]
    fn geo_is_deep_space() -> Result<(), Error> {
        // GEO: ~1.0 rev/day => period ~1440 min
        let mm = MeanMotion::new(1.0)?;
        assert_eq!(select_propagator(mm), PropagatorKind::Sdp4);
        Ok(())
    }

    #[test]
    fn boundary_is_deep_space() -> Result<(), Error> {
        // Exactly at boundary: 1440/225 = 6.4 rev/day
        let mm = MeanMotion::new(1440.0 / 225.0)?;
        assert_eq!(select_propagator(mm), PropagatorKind::Sdp4);
        Ok(())
    }

    #[test]
    fn just_above_boundary_is_near_earth() -> Result<(), Error> {
        let mm = MeanMotion::new(1440.0 / 224.9)?;
        assert_eq!(select_propagator(mm), PropagatorKind::Sgp4);
        Ok(())
    }
}
