//! Local copy of the bounded exponential-backoff helper.
//!
//! Duplicated from `mavlink_layer::internal::retry` rather than promoted to
//! `shared`; the two callsites have different defaults and retry policies and
//! the file is small enough that the SRP cost is lower than the cross-crate
//! coupling.

use std::time::Duration;

#[derive(Debug, Clone)]
pub struct ExponentialBackoff {
    base: Duration,
    cap: Duration,
    attempt: u32,
}

impl ExponentialBackoff {
    pub fn new(base: Duration, cap: Duration) -> Self {
        assert!(base > Duration::ZERO, "backoff base must be positive");
        assert!(cap >= base, "backoff cap must be >= base");
        Self {
            base,
            cap,
            attempt: 0,
        }
    }

    pub fn next_delay(&mut self) -> Duration {
        let exp = self.attempt.min(31);
        let delay = self
            .base
            .checked_mul(1u32 << exp)
            .unwrap_or(self.cap)
            .min(self.cap);
        self.attempt = self.attempt.saturating_add(1);
        delay
    }

    #[allow(dead_code)] // surfaced through tests + future health detail
    pub fn attempts(&self) -> u32 {
        self.attempt
    }
}
