use num_traits::AsPrimitive;

#[derive(Copy, Clone, Debug)]
pub struct RefillRate(pub(crate) f64);

impl RefillRate {
    /// This refill rate would reset the bucket completely to each maximum capacity every tick
    #[inline]
    pub fn max() -> Self {
        Self(f64::MAX)
    }

    #[inline]
    pub fn per_nano<T>(refill_rate_per_second: T) -> Self
    where
        T: AsPrimitive<f64>,
    {
        Self(refill_rate_per_second.as_())
    }
    #[inline]
    pub fn per_micro<T>(refill_rate_per_second: T) -> Self
    where
        T: AsPrimitive<f64>,
    {
        Self(refill_rate_per_second.as_() / 1_000.0)
    }
    #[inline]
    pub fn per_milli<T>(refill_rate_per_second: T) -> Self
    where
        T: AsPrimitive<f64>,
    {
        Self(refill_rate_per_second.as_() / 1_000_000.0)
    }
    #[inline]
    pub fn per_sec<T>(refill_rate_per_second: T) -> Self
    where
        T: AsPrimitive<f64>,
    {
        Self(refill_rate_per_second.as_() / 1_000_000_000.0)
    }

    #[inline]
    pub fn per_minute<T>(refill_rate_per_second: T) -> Self
    where
        T: AsPrimitive<f64>,
    {
        Self(refill_rate_per_second.as_() / 60_000_000_000.0)
    }

    #[inline]
    pub fn per_hour<T>(refill_rate_per_second: T) -> Self
    where
        T: AsPrimitive<f64>,
    {
        Self(refill_rate_per_second.as_() / 3600_000_000_000.0)
    }

    #[inline]
    pub fn per_day<T>(refill_rate_per_second: T) -> Self
    where
        T: AsPrimitive<f64>,
    {
        Self(refill_rate_per_second.as_() / 86400_000_000_000.0)
    }

    #[inline]
    pub fn per_week<T>(refill_rate_per_second: T) -> Self
    where
        T: AsPrimitive<f64>,
    {
        Self(refill_rate_per_second.as_() / 604800_000_000_000.0)
    }
}
