use std::{fs::File, sync::Arc};
use ntp_proto::{KeySet, KeySetProvider};
use tokio::sync::watch;
use tracing::{error, warn};
use crate::config::KeysetConfig;
pub async fn spawn(config: KeysetConfig) -> watch::Receiver<Arc<KeySet>> {
    let (mut provider, mut next_interval) = match &config.storage_path {
        Some(path) => {
            let path = path.to_owned();
            let (provider, time) = tokio::task::spawn_blocking(
                move || -> std::io::Result<(KeySetProvider, std::time::SystemTime)> {
                    let mut input = File::open(path)?;
                    KeySetProvider::load(&mut input, config.old_keys)
                },
            )
            .await
            .unwrap_or_else(|e| Err(std::io::Error::new(std::io::ErrorKind::Other, e)))
            .unwrap_or_else(|e| {
                error!(error = ?e, "Could not load nts server keys, starting with new set");
                (
                    KeySetProvider::new(config.old_keys),
                    std::time::SystemTime::now(),
                )
            });
            (
                provider,
                std::time::Duration::from_secs(config.rotation_interval as _).saturating_sub(
                    std::time::SystemTime::now()
                        .duration_since(time)
                        .unwrap_or(std::time::Duration::from_secs(0)),
                ),
            )
        }
        None => (
            KeySetProvider::new(config.old_keys),
            std::time::Duration::from_secs(config.rotation_interval as _),
        ),
    };
    let (tx, rx) = watch::channel(provider.get());
    tokio::task::spawn_blocking(move || loop {
        std::thread::sleep(next_interval);
        next_interval = std::time::Duration::from_secs(config.rotation_interval as _);
        provider.rotate();
        if let Some(path) = &config.storage_path {
            if let Err(e) = (|| -> std::io::Result<()> {
                let mut output = File::create(path)?;
                provider.store(&mut output)
            })() {
                warn!(error = ?e, "Could not store nts server keys");
            }
        }
        if tx.send(provider.get()).is_err() {
            break;
        }
    });
    rx
}