//! In-memory log capture, used by the audit tests to assert that
//! `tracing` output contains no secret material (SS-AUD-003).
//!
//! Production code will use the redaction policy defined in
//! `docs/security/diagnostic-redaction-audit-report.md` and the
//! `chanora_diagnostics` crate. This PoC is intentionally simpler:
//! it captures *all* log output verbatim and lets the test grep it.

use std::io::{self, Write};
use std::sync::{Arc, Mutex};

#[derive(Clone, Default)]
pub struct CapturedLog {
    buf: Arc<Mutex<Vec<u8>>>,
}

impl CapturedLog {
    pub fn new() -> Self {
        Self::default()
    }

    /// Snapshot the captured bytes as a UTF-8 string (lossy if there's
    /// any non-UTF-8 — we never expect non-UTF-8 from `tracing`).
    pub fn snapshot(&self) -> String {
        let buf = self.buf.lock().unwrap();
        String::from_utf8_lossy(&buf).into_owned()
    }

    pub fn writer(&self) -> CapturedLogWriter {
        CapturedLogWriter { buf: self.buf.clone() }
    }
}

pub struct CapturedLogWriter {
    buf: Arc<Mutex<Vec<u8>>>,
}

impl Write for CapturedLogWriter {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let mut g = self.buf.lock().unwrap();
        g.extend_from_slice(buf);
        Ok(buf.len())
    }
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

impl<'a> tracing_subscriber::fmt::MakeWriter<'a> for CapturedLog {
    type Writer = CapturedLogWriter;
    fn make_writer(&'a self) -> Self::Writer {
        self.writer()
    }
}
