// SPDX-FileCopyrightText: 2026 Contributors to brew-proxy <https://codeberg.org/HastD/brew-proxy>
//
// SPDX-License-Identifier: Apache-2.0 OR MIT

use std::{
    sync::{LazyLock, Mutex},
    time::{Duration, Instant},
};

pub fn idle_time() -> Option<Duration> {
    if let IdleTracker::IdleSince(timestamp) = *IDLE_TRACKER.lock().unwrap() {
        Some(timestamp.elapsed())
    } else {
        None
    }
}

pub fn init_idle_tracker() {
    LazyLock::force(&IDLE_TRACKER);
}

#[derive(Clone, Copy, Debug)]
enum IdleTracker {
    ActiveClients(u64),
    IdleSince(Instant),
}

static IDLE_TRACKER: LazyLock<Mutex<IdleTracker>> =
    LazyLock::new(|| Mutex::new(IdleTracker::IdleSince(Instant::now())));

/// Token to indicate that a client's request is active. Updates client count
/// when created or dropped; marks status as idle if client count becomes zero.
#[derive(Debug)]
pub struct ActiveClient(());

impl ActiveClient {
    pub fn new() -> Self {
        let mut idle_tracker = IDLE_TRACKER.lock().unwrap();
        let count = match *idle_tracker {
            IdleTracker::ActiveClients(x) => x.saturating_add(1),
            IdleTracker::IdleSince(_) => 1,
        };
        *idle_tracker = IdleTracker::ActiveClients(count);
        ActiveClient(())
    }
}

impl Default for ActiveClient {
    fn default() -> Self {
        Self::new()
    }
}

impl Drop for ActiveClient {
    fn drop(&mut self) {
        let mut idle_tracker = IDLE_TRACKER.lock().unwrap();
        let count = match *idle_tracker {
            IdleTracker::ActiveClients(x) => x.strict_sub(1),
            IdleTracker::IdleSince(_) => unreachable!("this client was active, so not idle"),
        };
        *idle_tracker = if count == 0 {
            IdleTracker::IdleSince(Instant::now())
        } else {
            IdleTracker::ActiveClients(count)
        };
    }
}
