//! Two-Line Element (TLE) set parsing and representation.
//!
//! Provides the [`Tle`] struct with validated newtypes for all orbital elements,
//! and a parser that returns `Io<Error, Tle>` for lazy, fallible parsing.

pub mod newtypes;
pub mod parse;

use newtypes::{
    ArgPerigee, Bstar, Classification, Eccentricity, ElementSetNumber, EpochDay, EpochYear,
    Inclination, MeanAnomaly, MeanMotion, MeanMotionDdot, MeanMotionDot, Raan, RevolutionNumber,
    SatelliteName, SatelliteNumber,
};

/// A parsed Two-Line Element set.
#[derive(Debug, Clone)]
pub struct Tle {
    name: SatelliteName,
    satellite_number: SatelliteNumber,
    classification: Classification,
    epoch_year: EpochYear,
    epoch_day: EpochDay,
    mean_motion_dot: MeanMotionDot,
    mean_motion_ddot: MeanMotionDdot,
    bstar: Bstar,
    element_set_number: ElementSetNumber,
    inclination: Inclination,
    raan: Raan,
    eccentricity: Eccentricity,
    arg_perigee: ArgPerigee,
    mean_anomaly: MeanAnomaly,
    mean_motion: MeanMotion,
    revolution_number: RevolutionNumber,
}

impl Tle {
    /// Construct a TLE from validated components.
    #[allow(clippy::too_many_arguments)]
    #[must_use]
    pub fn new(
        name: SatelliteName,
        satellite_number: SatelliteNumber,
        classification: Classification,
        epoch_year: EpochYear,
        epoch_day: EpochDay,
        mm_first_deriv: MeanMotionDot,
        mm_second_deriv: MeanMotionDdot,
        bstar: Bstar,
        element_set_number: ElementSetNumber,
        inclination: Inclination,
        raan: Raan,
        eccentricity: Eccentricity,
        arg_perigee: ArgPerigee,
        mean_anomaly: MeanAnomaly,
        mean_motion: MeanMotion,
        revolution_number: RevolutionNumber,
    ) -> Self {
        Self {
            name,
            satellite_number,
            classification,
            epoch_year,
            epoch_day,
            mean_motion_dot: mm_first_deriv,
            mean_motion_ddot: mm_second_deriv,
            bstar,
            element_set_number,
            inclination,
            raan,
            eccentricity,
            arg_perigee,
            mean_anomaly,
            mean_motion,
            revolution_number,
        }
    }

    #[must_use]
    pub fn name(&self) -> &SatelliteName {
        &self.name
    }
    #[must_use]
    pub fn satellite_number(&self) -> SatelliteNumber {
        self.satellite_number
    }
    #[must_use]
    pub fn classification(&self) -> Classification {
        self.classification
    }
    #[must_use]
    pub fn epoch_year(&self) -> EpochYear {
        self.epoch_year
    }
    #[must_use]
    pub fn epoch_day(&self) -> EpochDay {
        self.epoch_day
    }
    #[must_use]
    pub fn mean_motion_dot(&self) -> MeanMotionDot {
        self.mean_motion_dot
    }
    #[must_use]
    pub fn mean_motion_ddot(&self) -> MeanMotionDdot {
        self.mean_motion_ddot
    }
    #[must_use]
    pub fn bstar(&self) -> Bstar {
        self.bstar
    }
    #[must_use]
    pub fn element_set_number(&self) -> ElementSetNumber {
        self.element_set_number
    }
    #[must_use]
    pub fn inclination(&self) -> Inclination {
        self.inclination
    }
    #[must_use]
    pub fn raan(&self) -> Raan {
        self.raan
    }
    #[must_use]
    pub fn eccentricity(&self) -> Eccentricity {
        self.eccentricity
    }
    #[must_use]
    pub fn arg_perigee(&self) -> ArgPerigee {
        self.arg_perigee
    }
    #[must_use]
    pub fn mean_anomaly(&self) -> MeanAnomaly {
        self.mean_anomaly
    }
    #[must_use]
    pub fn mean_motion(&self) -> MeanMotion {
        self.mean_motion
    }
    #[must_use]
    pub fn revolution_number(&self) -> RevolutionNumber {
        self.revolution_number
    }
}
