//! Admin / inspection methods on `Archivist`.
//!
//! Split out because they aren't part of the hot-path coordinator API:
//! `shutdown` drains queued writer tasks, `list_archives_with_health`
//! snapshots every registration's health + queue depth, and the cache
//! admin methods delegate to `ReadCache`.

use std::sync::Arc;

use tokio::sync::oneshot;

use crate::error::Result;
use crate::registry::writer::WriteOp;
use crate::registry::{ArchiveRegistration, ArchiveStatus};

use super::Archivist;

impl Archivist {
    /// Drain every queued writer task. Inline backends are no-ops.
    /// Call before process exit to ensure in-flight batches land.
    pub async fn shutdown(&self) -> Result<()> {
        let regs: Vec<Arc<ArchiveRegistration>> = self.registrations.read().await.clone();
        for reg in regs.iter() {
            if let Some(writer) = reg.writer.as_ref() {
                let (tx, rx) = oneshot::channel();
                // If the send fails, the writer task has already exited — skip the wait.
                if writer.sender.send(WriteOp::Shutdown(tx)).await.is_ok() {
                    let _ = rx.await;
                }
                // Join the task, if it's still attached.
                if let Some(handle) = writer.join.lock().await.take() {
                    let _ = handle.await;
                }
            }
        }
        Ok(())
    }

    /// Snapshot every registered archive's current status.
    pub async fn list_archives_with_health(&self) -> Vec<ArchiveStatus> {
        let regs: Vec<Arc<ArchiveRegistration>> = self.registrations.read().await.clone();
        let mut out = Vec::with_capacity(regs.len());
        for reg in regs.iter() {
            let health = reg.last_health.read().await.clone();
            let last_error = reg.last_error.read().await.clone();
            let queue_depth = reg.writer.as_ref().map(|w| w.queue_depth_now());
            out.push(ArchiveStatus {
                name: reg.name.clone(),
                type_name: reg.type_name.to_string(),
                enabled: reg.enabled,
                write_active: reg.write_active,
                failure_mode: reg.failure_mode,
                read_priority: reg.read_priority,
                capabilities: reg.capabilities().clone(),
                health,
                last_error,
                queue_depth,
            });
        }
        out
    }

    pub async fn clear_read_cache(&self) {
        self.read_cache.clear().await;
    }

    pub async fn read_cache_size(&self) -> usize {
        self.read_cache.len().await
    }
}
