// Copyright 2023 Google LLC
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! Debug command traits and helpers for defining commands for integration
//! into a debug tool.
use futures::channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender};
use futures::task::AtomicWaker;
use futures::{FutureExt, Stream, StreamExt};
use log::LevelFilter;
use std::collections::HashMap;
use std::pin::Pin;
use std::str::FromStr;
use std::sync::{Arc, Mutex};
use std::task::{Context, Poll};

#[must_use = "if unused the previous log level will immediately be restored"]
pub struct ScopedVerbosityGuard {
    prev_level: LevelFilter,
}

impl ScopedVerbosityGuard {
    pub fn new(scoped_level: LevelFilter) -> Self {
        let prev_level = log::max_level();
        log::set_max_level(scoped_level);
        Self { prev_level }
    }
}

impl Drop for ScopedVerbosityGuard {
    fn drop(&mut self) {
        log::set_max_level(self.prev_level);
    }
}

pub fn parse_level_filter(s: &str) -> Option<LevelFilter> {
    s.trim().parse().ok()
}

pub fn extract_verbosity_flags(args: Vec<String>) -> (Option<LevelFilter>, Vec<String>) {
    let mut level = None;
    let mut clean_args = Vec::new();
    let mut iter = args.into_iter().peekable();

    while let Some(arg) = iter.next() {
        match arg.as_str() {
            "-v" | "--verbose" => {
                level = Some(LevelFilter::Debug);
            }
            "-vv" | "--trace" => {
                level = Some(LevelFilter::Trace);
            }
            "-q" | "--quiet" => {
                level = Some(LevelFilter::Warn);
            }
            "--log-level" => {
                if let Some(next) = iter.peek() {
                    if let Some(lvl) = parse_level_filter(next) {
                        level = Some(lvl);
                        iter.next();
                        continue;
                    }
                }
                clean_args.push(arg);
            }
            _ if arg.starts_with("--log-level=") => {
                let val = &arg["--log-level=".len()..];
                if let Some(lvl) = parse_level_filter(val) {
                    level = Some(lvl);
                } else {
                    clean_args.push(arg);
                }
            }
            _ => {
                clean_args.push(arg);
            }
        }
    }

    (level, clean_args)
}

pub fn handle_verbose_command(args: &[String]) {
    match args.len() {
        0 => {
            println!("Current log level: {}", log::max_level());
        }
        1 => {
            if let Some(level) = parse_level_filter(&args[0]) {
                log::set_max_level(level);
                println!("Log level set to {}", level);
            } else {
                eprintln!(
                    "Invalid log level '{}'. Valid levels: off, error, warn, info, debug, trace",
                    args[0]
                );
            }
        }
        _ => {
            println!("Usage: verbose [off|error|warn|info|debug|trace]");
        }
    }
}

/// A CommandSet is a set of commands (usually an enum) that each represent an
/// action that can be performed.  i.e. 'list', 'volume' etc.  Each command can
/// take zero or more arguments and have zero or more flags.
/// Typically an Enum of commands would implement CommandSet trait.
pub trait CommandSet: FromStr + ::core::fmt::Display {
    /// Returns a vector of strings that are the commands supported by this.
    fn variants() -> Vec<String>;

    /// Returns a string listing the arguments that this command takes, in <>
    /// brackets
    fn arguments(&self) -> &'static str;

    /// Returns a string displaying the flags that this command supports, in []
    /// brackets
    fn flags(&self) -> &'static str;

    /// Returns a short description of this command
    fn desc(&self) -> &'static str;

    /// Help string for this variant (build from Display, arguments and flags by
    /// default)
    fn help_simple(&self) -> String {
        format!("{self} {} {} -- {}", self.flags(), self.arguments(), self.desc())
    }

    /// Possibly multi-line help string for all variants of this set.
    fn help_all() -> String {
        let mut help: String = Self::variants()
            .into_iter()
            .filter_map(|s| FromStr::from_str(&s).ok())
            .map(|s: Self| format!("{}\n", s))
            .collect();
        if !help.is_empty() {
            help.push('\n');
        }
        help.push_str("Global verbosity flags: [-v|--verbose] [-vv|--trace] [-q|--quiet] [--log-level=<level>]\n");
        help
    }
}

/// A top-level CLI command: either a framework meta-command (e.g. `verbose`)
/// or a profile-specific domain command.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum CliCommand<T> {
    Verbose,
    Domain(T),
}

impl<T> From<T> for CliCommand<T> {
    fn from(cmd: T) -> Self {
        CliCommand::Domain(cmd)
    }
}

impl<T: CommandSet> CommandSet for CliCommand<T> {
    fn variants() -> Vec<String> {
        let mut variants = T::variants();
        variants.push("verbose".to_string());
        variants
    }

    fn arguments(&self) -> &'static str {
        match self {
            CliCommand::Domain(cmd) => cmd.arguments(),
            CliCommand::Verbose => "[level] ",
        }
    }

    fn flags(&self) -> &'static str {
        match self {
            CliCommand::Domain(cmd) => cmd.flags(),
            CliCommand::Verbose => "",
        }
    }

    fn desc(&self) -> &'static str {
        match self {
            CliCommand::Domain(cmd) => cmd.desc(),
            CliCommand::Verbose => "Get or set the logging verbosity level",
        }
    }
}

impl<T: ::core::fmt::Display> ::core::fmt::Display for CliCommand<T> {
    fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
        match self {
            CliCommand::Domain(cmd) => write!(f, "{cmd}"),
            CliCommand::Verbose => write!(f, "verbose"),
        }
    }
}

impl<T: FromStr> FromStr for CliCommand<T> {
    type Err = T::Err;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s == "verbose" {
            Ok(CliCommand::Verbose)
        } else {
            T::from_str(s).map(CliCommand::Domain)
        }
    }
}

/// Macro to help build CommandSets
#[macro_export]
macro_rules! gen_commandset {
    ($name:ident {
        $($variant:ident = ($val:expr, [$($flag:expr),*], [$($arg:expr),*], $help:expr)),*,
    }) => {
        /// Enum of all possible commands
        #[derive(PartialEq, Debug, Clone, Copy)]
        pub enum $name {
            $($variant,)*
        }

        impl CommandSet for $name {
            fn variants() -> Vec<String> {
                let mut variants = Vec::new();
                $(variants.push($val.to_string());)*
                variants
            }

            fn arguments(&self) -> &'static str {
                match self {
                    $(
                        $name::$variant => concat!($("<", $arg, "> ",)*),
                    )*
                }
            }

            fn flags(&self) -> &'static str {
                match self {
                    $(
                        $name::$variant => concat!($("[", $flag, "] ",)*),
                    )*
                }
            }

            fn desc(&self) -> &'static str {
                match self {
                    $(
                        $name::$variant => $help,
                    )*
                }
            }
        }

        impl ::core::fmt::Display for $name {
            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
                match *self {
                    $($name::$variant => write!(f, $val),)*
                }
            }
        }

        impl ::std::str::FromStr for $name {
            type Err = ();

            fn from_str(s: &str) -> Result<$name, ()> {
                match s {
                    $($val => Ok($name::$variant),)*
                    _ => Err(()),
                }
            }
        }
    }
}

/// An event emitted by a [`CommandRunner`] through its
/// [`CommandRunner::event_stream`].
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum RunnerEvent<E = ()> {
    /// An arbitrary human-readable message from the runner or its background
    /// tasks to be displayed by the harness.
    Message(String),
    /// A structured domain event specific to this runner that the harness or a
    /// parent composite tool can react to programmatically.
    Event(E),
}

impl<E> RunnerEvent<E> {
    pub fn message(&self) -> Option<&str> {
        match self {
            Self::Message(s) => Some(s),
            Self::Event(_) => None,
        }
    }

    pub fn event(&self) -> Option<&E> {
        match self {
            Self::Message(_) => None,
            Self::Event(e) => Some(e),
        }
    }

    pub fn into_event(self) -> Option<E> {
        match self {
            Self::Message(_) => None,
            Self::Event(e) => Some(e),
        }
    }

    pub fn into_message(self) -> Option<String> {
        match self {
            Self::Message(s) => Some(s),
            Self::Event(_) => None,
        }
    }

    pub fn map_event<F, T>(self, f: F) -> RunnerEvent<T>
    where
        F: FnOnce(E) -> T,
    {
        match self {
            Self::Message(m) => RunnerEvent::Message(m),
            Self::Event(e) => RunnerEvent::Event(f(e)),
        }
    }
}

impl<E> From<String> for RunnerEvent<E> {
    fn from(s: String) -> Self {
        Self::Message(s)
    }
}

impl<E> From<&str> for RunnerEvent<E> {
    fn from(s: &str) -> Self {
        Self::Message(s.to_string())
    }
}

/// CommandRunner is used to perform a specific task based on the command set.
pub trait CommandRunner {
    type Set: CommandSet;
    type Error: ::std::error::Error;
    type Event;

    fn run_command(
        &self,
        cmd: Self::Set,
        args: Vec<String>,
    ) -> impl futures::Future<Output = Result<(), Self::Error>>;

    /// Returns a stream that drives background processing for this runner and
    /// yields display messages or structured events for the harness.
    ///
    /// Crates that do not need background tasks or event delivery can set
    /// `type Event = ();` and rely on this default implementation.
    fn event_stream(&self) -> impl Stream<Item = RunnerEvent<Self::Event>> + '_ {
        futures::stream::pending::<RunnerEvent<Self::Event>>()
    }

    fn run(
        &self,
        cmd: impl Into<CliCommand<Self::Set>>,
        args: Vec<String>,
    ) -> impl futures::Future<Output = Result<(), Self::Error>> {
        let cmd = cmd.into();
        async move {
            match cmd {
                CliCommand::Verbose => {
                    handle_verbose_command(&args);
                    Ok(())
                }
                CliCommand::Domain(cmd) => {
                    let (scoped_level, clean_args) = extract_verbosity_flags(args);
                    let _guard = scoped_level.map(ScopedVerbosityGuard::new);
                    self.run_command(cmd, clean_args).await
                }
            }
        }
    }
}

impl<R: CommandRunner> CommandRunner for &R {
    type Set = R::Set;
    type Error = R::Error;
    type Event = R::Event;

    fn run_command(
        &self,
        cmd: Self::Set,
        args: Vec<String>,
    ) -> impl futures::Future<Output = Result<(), Self::Error>> {
        (**self).run_command(cmd, args)
    }

    fn event_stream(&self) -> impl Stream<Item = RunnerEvent<Self::Event>> + '_ {
        (**self).event_stream()
    }
}

impl<R: CommandRunner> CommandRunner for Arc<R> {
    type Set = R::Set;
    type Error = R::Error;
    type Event = R::Event;

    fn run_command(
        &self,
        cmd: Self::Set,
        args: Vec<String>,
    ) -> impl futures::Future<Output = Result<(), Self::Error>> {
        (**self).run_command(cmd, args)
    }

    fn event_stream(&self) -> impl Stream<Item = RunnerEvent<Self::Event>> + '_ {
        (**self).event_stream()
    }
}

type BoxedStream<E> = Pin<Box<dyn Stream<Item = RunnerEvent<E>> + Send + 'static>>;

struct StreamsState<E> {
    keyed: HashMap<String, BoxedStream<E>>,
    anonymous: Vec<BoxedStream<E>>,
}

impl<E> Default for StreamsState<E> {
    fn default() -> Self {
        Self { keyed: HashMap::new(), anonymous: Vec::new() }
    }
}

impl<E: Send + 'static> Stream for StreamsState<E> {
    type Item = RunnerEvent<E>;

    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
        let mut ready = None;
        self.keyed.retain(|_key, stream| {
            if ready.is_some() {
                return true;
            }
            match stream.as_mut().poll_next(cx) {
                Poll::Ready(Some(item)) => {
                    ready = Some(item);
                    true
                }
                Poll::Ready(None) => false,
                Poll::Pending => true,
            }
        });
        if let Some(item) = ready {
            return Poll::Ready(Some(item));
        }

        self.anonymous.retain_mut(|stream| {
            if ready.is_some() {
                return true;
            }
            match stream.as_mut().poll_next(cx) {
                Poll::Ready(Some(item)) => {
                    ready = Some(item);
                    true
                }
                Poll::Ready(None) => false,
                Poll::Pending => true,
            }
        });
        if let Some(item) = ready {
            return Poll::Ready(Some(item));
        }

        Poll::Pending
    }
}

struct RunnerBackgroundInner<E: Send + 'static> {
    msg_sender: UnboundedSender<RunnerEvent<E>>,
    msg_receiver: Mutex<UnboundedReceiver<RunnerEvent<E>>>,
    streams: Mutex<StreamsState<E>>,
    waker: AtomicWaker,
}

/// Helper for managing background streams, display messages, and structured
/// events for a [`CommandRunner`].
#[derive(Clone)]
pub struct RunnerBackground<E: Send + 'static = ()> {
    inner: Arc<RunnerBackgroundInner<E>>,
}

impl<E: Send + 'static> RunnerBackground<E> {
    pub fn new() -> Self {
        let (msg_sender, msg_receiver) = unbounded();
        Self {
            inner: Arc::new(RunnerBackgroundInner {
                msg_sender,
                msg_receiver: Mutex::new(msg_receiver),
                streams: Mutex::new(StreamsState::default()),
                waker: AtomicWaker::new(),
            }),
        }
    }

    /// Queues a displayable text message to be emitted by
    /// [`Self::event_stream`].
    pub fn println(&self, msg: impl Into<String>) {
        let _ = self.inner.msg_sender.unbounded_send(RunnerEvent::Message(msg.into()));
        self.inner.waker.wake();
    }

    /// Queues a structured domain event to be emitted by
    /// [`Self::event_stream`].
    pub fn send(&self, event: E) {
        let _ = self.inner.msg_sender.unbounded_send(RunnerEvent::Event(event));
        self.inner.waker.wake();
    }

    /// Returns an [`UnboundedSender`] that converts sent items into
    /// [`RunnerEvent::Event`].
    pub fn event_sender(&self) -> UnboundedSender<E> {
        let (tx, rx) = unbounded::<E>();
        self.spawn_stream(rx.map(RunnerEvent::Event));
        tx
    }

    /// Dynamically registers or replaces a background stream under a unique
    /// key. If a stream was already registered under `key`, the previous
    /// stream is cancelled.
    pub fn set_stream<K: Into<String>>(
        &self,
        key: K,
        stream: impl Stream<Item = RunnerEvent<E>> + Send + 'static,
    ) {
        let mut streams = self.inner.streams.lock().unwrap();
        streams.keyed.insert(key.into(), Box::pin(stream));
        drop(streams);
        self.inner.waker.wake();
    }

    /// Cancels the stream registered under `key`, if present. Returns `true` if
    /// a stream was cancelled.
    pub fn cancel_stream(&self, key: &str) -> bool {
        let mut streams = self.inner.streams.lock().unwrap();
        let removed = streams.keyed.remove(key).is_some();
        drop(streams);
        if removed {
            self.inner.waker.wake();
        }
        removed
    }

    /// Spawns an anonymous background stream that runs until completion.
    pub fn spawn_stream(&self, stream: impl Stream<Item = RunnerEvent<E>> + Send + 'static) {
        let mut streams = self.inner.streams.lock().unwrap();
        streams.anonymous.push(Box::pin(stream));
        drop(streams);
        self.inner.waker.wake();
    }

    /// Returns `true` if a background stream is currently registered under
    /// `key`.
    pub fn has_stream(&self, key: &str) -> bool {
        self.inner.streams.lock().unwrap().keyed.contains_key(key)
    }

    /// Returns the total number of active background streams (keyed and
    /// anonymous).
    pub fn active_stream_count(&self) -> usize {
        let streams = self.inner.streams.lock().unwrap();
        streams.keyed.len() + streams.anonymous.len()
    }

    /// Returns a stream yielding messages and events produced by this runner.
    pub fn event_stream(&self) -> RunnerBackgroundStream<E> {
        RunnerBackgroundStream { inner: self.inner.clone() }
    }
}

impl<E: Send + 'static> RunnerBackgroundInner<E> {
    fn poll_next_event(&self, cx: &mut Context<'_>) -> Poll<Option<RunnerEvent<E>>> {
        self.waker.register(cx.waker());

        // 1. Drain directly queued messages/events from msg_receiver first.
        if let Poll::Ready(Some(item)) = self.msg_receiver.lock().unwrap().poll_next_unpin(cx) {
            return Poll::Ready(Some(item));
        }

        // 2. Poll registered background streams.
        if let Poll::Ready(Some(item)) = self.streams.lock().unwrap().poll_next_unpin(cx) {
            return Poll::Ready(Some(item));
        }

        Poll::Pending
    }
}

impl<E: Send + 'static> Default for RunnerBackground<E> {
    fn default() -> Self {
        Self::new()
    }
}

/// Stream returned by [`RunnerBackground::event_stream`].
pub struct RunnerBackgroundStream<E: Send + 'static = ()> {
    inner: Arc<RunnerBackgroundInner<E>>,
}

impl<E: Send + 'static> Stream for RunnerBackgroundStream<E> {
    type Item = RunnerEvent<E>;

    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
        self.inner.poll_next_event(cx)
    }
}

/// A harness for driving a [`CommandRunner`] alongside its background event
/// stream.
pub struct DebugHarness<R: CommandRunner> {
    runner: R,
}

impl<R: CommandRunner> DebugHarness<R> {
    pub fn new(runner: R) -> Self {
        Self { runner }
    }

    pub fn runner(&self) -> &R {
        &self.runner
    }

    pub fn runner_mut(&mut self) -> &mut R {
        &mut self.runner
    }

    pub fn into_runner(self) -> R {
        self.runner
    }

    pub fn event_stream(&self) -> impl Stream<Item = RunnerEvent<R::Event>> + '_ {
        self.runner.event_stream()
    }

    pub async fn run(
        &self,
        cmd: impl Into<CliCommand<R::Set>>,
        args: Vec<String>,
    ) -> Result<(), R::Error> {
        self.runner.run(cmd, args).await
    }

    async fn drive_events<Fut, F>(&self, future: Fut, mut on_event: F) -> Fut::Output
    where
        Fut: futures::Future,
        F: FnMut(RunnerEvent<R::Event>),
    {
        let stream = self.runner.event_stream().fuse();
        futures::pin_mut!(stream);
        let future = future.fuse();
        futures::pin_mut!(future);

        loop {
            futures::select! {
                event = stream.select_next_some() => on_event(event),
                output = future => {
                    while let Some(Some(event)) = stream.next().now_or_never() {
                        on_event(event);
                    }
                    return output;
                }
            }
        }
    }

    /// Concurrently drives the runner's background `event_stream` while
    /// executing `future`. Messages are passed to `on_message` and events
    /// are passed to `on_event`.
    pub async fn drive_with<Fut, FM, FE>(
        &self,
        future: Fut,
        mut on_message: FM,
        mut on_event: FE,
    ) -> Fut::Output
    where
        Fut: futures::Future,
        FM: FnMut(String),
        FE: FnMut(R::Event),
    {
        self.drive_events(future, |event| match event {
            RunnerEvent::Message(msg) => on_message(msg),
            RunnerEvent::Event(evt) => on_event(evt),
        })
        .await
    }

    /// Concurrently executes `future` while collecting all `RunnerEvent`s
    /// emitted during its execution.
    pub async fn run_collecting_events<Fut>(
        &self,
        future: Fut,
    ) -> (Fut::Output, Vec<RunnerEvent<R::Event>>)
    where
        Fut: futures::Future,
    {
        let mut events = Vec::new();
        let output = self.drive_events(future, |event| events.push(event)).await;
        (output, events)
    }

    /// Concurrently executes a command while collecting all `RunnerEvent`s
    /// emitted during its execution.
    pub async fn run_command_collecting(
        &self,
        cmd: impl Into<CliCommand<R::Set>>,
        args: Vec<String>,
    ) -> (Result<(), R::Error>, Vec<RunnerEvent<R::Event>>) {
        self.run_collecting_events(self.run(cmd, args)).await
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn gen_commandset_simple() {
        gen_commandset! {
            TestCmd {
                One = ("one", [], [], "First Command"),
                WithFlags = ("with-flags", ["-1","-2"], [], "Command with flags"),
                WithArgs = ("with-args", [], ["arg", "two"], "Command with args"),
                WithBoth = ("with-both", ["-w"], ["simple"], "Command with both flags and args"),
            }
        }

        let cmd: TestCmd = "one".parse().unwrap();
        assert_eq!(cmd, TestCmd::One);

        let cmd2: TestCmd = "with-flags".parse().unwrap();
        assert_eq!(cmd2.arguments(), "");
        assert_eq!(cmd2.flags(), "[-1] [-2] ");

        let verbose_cmd: CliCommand<TestCmd> = "verbose".parse().unwrap();
        assert_eq!(verbose_cmd, CliCommand::Verbose);
        assert_eq!(verbose_cmd.flags(), "");
        assert_eq!(verbose_cmd.to_string(), "verbose");

        let domain_cmd: CliCommand<TestCmd> = "one".parse().unwrap();
        assert_eq!(domain_cmd, CliCommand::Domain(TestCmd::One));

        assert!(!TestCmd::variants().contains(&"verbose".to_string()));
        assert!(CliCommand::<TestCmd>::variants().contains(&"verbose".to_string()));
        assert!(TestCmd::help_all().contains("Global verbosity flags:"));
        assert!(CliCommand::<TestCmd>::help_all().contains("Global verbosity flags:"));
    }

    #[test]
    fn test_extract_verbosity_flags() {
        // -v / --verbose
        let (lvl, args) = extract_verbosity_flags(vec!["-v".to_string()]);
        assert_eq!(lvl, Some(LevelFilter::Debug));
        assert!(args.is_empty());

        let (lvl, args) = extract_verbosity_flags(vec!["--verbose".to_string()]);
        assert_eq!(lvl, Some(LevelFilter::Debug));
        assert!(args.is_empty());

        // -vv / --trace
        let (lvl, args) = extract_verbosity_flags(vec!["-vv".to_string()]);
        assert_eq!(lvl, Some(LevelFilter::Trace));
        assert!(args.is_empty());

        let (lvl, args) = extract_verbosity_flags(vec!["--trace".to_string()]);
        assert_eq!(lvl, Some(LevelFilter::Trace));
        assert!(args.is_empty());

        // -q / --quiet
        let (lvl, args) = extract_verbosity_flags(vec!["-q".to_string()]);
        assert_eq!(lvl, Some(LevelFilter::Warn));
        assert!(args.is_empty());

        let (lvl, args) = extract_verbosity_flags(vec!["--quiet".to_string()]);
        assert_eq!(lvl, Some(LevelFilter::Warn));
        assert!(args.is_empty());

        // --log-level=<level> and --log-level <level> (case-insensitive)
        for (name, expected) in [
            ("off", LevelFilter::Off),
            ("error", LevelFilter::Error),
            ("warn", LevelFilter::Warn),
            ("info", LevelFilter::Info),
            ("debug", LevelFilter::Debug),
            ("trace", LevelFilter::Trace),
            ("DEBUG", LevelFilter::Debug),
            ("Info", LevelFilter::Info),
        ] {
            let (lvl, args) = extract_verbosity_flags(vec![format!("--log-level={name}")]);
            assert_eq!(lvl, Some(expected));
            assert!(args.is_empty());

            let (lvl, args) =
                extract_verbosity_flags(vec!["--log-level".to_string(), name.to_string()]);
            assert_eq!(lvl, Some(expected));
            assert!(args.is_empty());
        }

        // Mixed arguments
        let input = vec![
            "action".to_string(),
            "-v".to_string(),
            "--custom-flag".to_string(),
            "target".to_string(),
            "--log-level=warn".to_string(),
            "extra".to_string(),
        ];
        let (lvl, args) = extract_verbosity_flags(input);
        assert_eq!(lvl, Some(LevelFilter::Warn));
        assert_eq!(args, vec!["action", "--custom-flag", "target", "extra"]);

        // Invalid log level flag should not be extracted
        let (lvl, args) =
            extract_verbosity_flags(vec!["--log-level=invalid".to_string(), "arg".to_string()]);
        assert_eq!(lvl, None);
        assert_eq!(args, vec!["--log-level=invalid", "arg"]);
    }

    // Mutex to avoid parallel tests fighting over log levels
    static LOG_MUTEX: std::sync::Mutex<()> = std::sync::Mutex::new(());

    #[test]
    fn test_scoped_verbosity_guard() {
        let _lock = LOG_MUTEX.lock().unwrap();
        log::set_max_level(LevelFilter::Info);

        futures::executor::block_on(async {
            assert_eq!(log::max_level(), LevelFilter::Info);
            {
                let _guard = ScopedVerbosityGuard::new(LevelFilter::Trace);
                assert_eq!(log::max_level(), LevelFilter::Trace);
                // Yield across async boundary
                futures::future::ready(()).await;
                assert_eq!(log::max_level(), LevelFilter::Trace);
            }
            assert_eq!(log::max_level(), LevelFilter::Info);
        });
    }

    #[test]
    fn test_persistent_verbosity_and_handle_command() {
        let _lock = LOG_MUTEX.lock().unwrap();
        log::set_max_level(LevelFilter::Debug);

        // handle_verbose_command with 0 args
        handle_verbose_command(&[]);
        assert_eq!(log::max_level(), LevelFilter::Debug);

        // handle_verbose_command with 1 valid arg
        handle_verbose_command(&["trace".to_string()]);
        assert_eq!(log::max_level(), LevelFilter::Trace);

        handle_verbose_command(&["WARN".to_string()]);
        assert_eq!(log::max_level(), LevelFilter::Warn);

        // handle_verbose_command with invalid arg (should not change)
        handle_verbose_command(&["invalid_level".to_string()]);
        assert_eq!(log::max_level(), LevelFilter::Warn);

        // handle_verbose_command with > 1 args (should not change)
        handle_verbose_command(&["info".to_string(), "extra".to_string()]);
        assert_eq!(log::max_level(), LevelFilter::Warn);

        // Reset back to Info
        log::set_max_level(LevelFilter::Info);
    }

    #[test]
    fn test_command_runner_run() {
        gen_commandset! {
            RunnerCmd {
                Action = ("action", [], ["target"], "Perform action"),
            }
        }

        struct TestRunner {
            executed: std::sync::Mutex<Vec<(RunnerCmd, Vec<String>)>>,
        }

        impl CommandRunner for TestRunner {
            type Set = RunnerCmd;
            type Error = std::io::Error;
            type Event = ();

            fn run_command(
                &self,
                cmd: Self::Set,
                args: Vec<String>,
            ) -> impl futures::Future<Output = Result<(), Self::Error>> {
                self.executed.lock().unwrap().push((cmd, args));
                futures::future::ready(Ok(()))
            }
        }

        let runner = TestRunner { executed: std::sync::Mutex::new(Vec::new()) };
        let _lock = LOG_MUTEX.lock().unwrap();

        // Running Verbose command should update persistent verbosity and NOT
        // invoke run_command
        log::set_max_level(LevelFilter::Info);
        futures::executor::block_on(runner.run(CliCommand::Verbose, vec!["trace".to_string()]))
            .unwrap();
        assert_eq!(log::max_level(), LevelFilter::Trace);
        assert!(runner.executed.lock().unwrap().is_empty());

        // Running normal command with verbosity flag strips flag and runs
        // command
        let args = vec!["-v".to_string(), "my_target".to_string()];
        futures::executor::block_on(runner.run(RunnerCmd::Action, args)).unwrap();
        let executed = runner.executed.lock().unwrap().clone();
        assert_eq!(executed.len(), 1);
        assert_eq!(executed[0], (RunnerCmd::Action, vec!["my_target".to_string()]));

        // After run completes, the guard has restored the previous level
        assert_eq!(log::max_level(), LevelFilter::Trace);

        // Reset persistent verbosity back to Info
        log::set_max_level(LevelFilter::Info);
    }

    #[test]
    fn test_command_runner_default_event_stream() {
        gen_commandset! {
            DefaultCmd {
                Action = ("action", [], [], "Default action"),
            }
        }

        struct SimpleRunner;
        impl CommandRunner for SimpleRunner {
            type Set = DefaultCmd;
            type Error = std::io::Error;
            type Event = ();

            fn run_command(
                &self,
                _cmd: Self::Set,
                _args: Vec<String>,
            ) -> impl futures::Future<Output = Result<(), Self::Error>> {
                futures::future::ready(Ok(()))
            }
        }

        let runner = SimpleRunner;
        let stream = runner.event_stream();
        futures::pin_mut!(stream);
        let mut cx = std::task::Context::from_waker(futures::task::noop_waker_ref());
        assert!(stream.as_mut().poll_next(&mut cx).is_pending());
    }

    #[test]
    fn test_runner_event() {
        let msg: RunnerEvent<u32> = RunnerEvent::Message("hello".to_string());
        assert_eq!(msg.message(), Some("hello"));
        assert_eq!(msg.event(), None);
        assert_eq!(msg.clone().into_event(), None);
        assert_eq!(msg.clone().into_message(), Some("hello".to_string()));

        let evt: RunnerEvent<u32> = RunnerEvent::Event(42);
        assert_eq!(evt.message(), None);
        assert_eq!(evt.event(), Some(&42));
        assert_eq!(evt.clone().into_event(), Some(42));
        assert_eq!(evt.into_message(), None);

        let str_msg: RunnerEvent<()> = "test msg".into();
        assert_eq!(str_msg, RunnerEvent::Message("test msg".to_string()));

        let string_msg: RunnerEvent<()> = String::from("string msg").into();
        assert_eq!(string_msg, RunnerEvent::Message("string msg".to_string()));

        let mapped = RunnerEvent::Event(10).map_event(|x| x * 2);
        assert_eq!(mapped, RunnerEvent::Event(20));

        let mapped_msg: RunnerEvent<i32> =
            RunnerEvent::Message("hi".to_string()).map_event(|x: u32| x as i32);
        assert_eq!(mapped_msg, RunnerEvent::Message("hi".to_string()));
    }

    #[test]
    fn test_runner_background_println_and_send() {
        futures::executor::block_on(async {
            let bg: RunnerBackground<u32> = RunnerBackground::new();
            bg.println("log message 1");
            bg.send(100);
            bg.println("log message 2");

            let stream = bg.event_stream();
            futures::pin_mut!(stream);

            assert_eq!(
                stream.next().await,
                Some(RunnerEvent::Message("log message 1".to_string()))
            );
            assert_eq!(stream.next().await, Some(RunnerEvent::Event(100)));
            assert_eq!(
                stream.next().await,
                Some(RunnerEvent::Message("log message 2".to_string()))
            );

            // When no more events, polling should return Pending.
            let mut cx = std::task::Context::from_waker(futures::task::noop_waker_ref());
            assert!(stream.as_mut().poll_next(&mut cx).is_pending());
        });
    }

    #[test]
    fn test_runner_background_event_sender() {
        futures::executor::block_on(async {
            let bg: RunnerBackground<String> = RunnerBackground::new();
            let sender = bg.event_sender();

            sender.unbounded_send("hello".to_string()).unwrap();
            sender.unbounded_send("world".to_string()).unwrap();

            let stream = bg.event_stream();
            futures::pin_mut!(stream);

            assert_eq!(stream.next().await, Some(RunnerEvent::Event("hello".to_string())));
            assert_eq!(stream.next().await, Some(RunnerEvent::Event("world".to_string())));

            drop(sender);
            // Polling after dropping sender should clean up the stream and
            // return Pending.
            let mut cx = std::task::Context::from_waker(futures::task::noop_waker_ref());
            assert!(stream.as_mut().poll_next(&mut cx).is_pending());
            assert_eq!(bg.active_stream_count(), 0);
        });
    }

    #[test]
    fn test_runner_background_keyed_streams_and_cancellation() {
        futures::executor::block_on(async {
            let bg: RunnerBackground<u32> = RunnerBackground::new();
            assert_eq!(bg.has_stream("discovery"), false);

            let (tx1, rx1) = futures::channel::mpsc::unbounded::<RunnerEvent<u32>>();
            bg.set_stream("discovery", rx1);
            assert_eq!(bg.has_stream("discovery"), true);
            assert_eq!(bg.active_stream_count(), 1);

            tx1.unbounded_send(RunnerEvent::Event(1)).unwrap();
            let stream = bg.event_stream();
            futures::pin_mut!(stream);
            assert_eq!(stream.next().await, Some(RunnerEvent::Event(1)));

            // Replacing the stream cancels the old one.
            let (tx2, rx2) = futures::channel::mpsc::unbounded::<RunnerEvent<u32>>();
            bg.set_stream("discovery", rx2);
            assert_eq!(bg.has_stream("discovery"), true);
            // Old tx1 should have receiver dropped / closed.
            assert!(tx1.is_closed());

            tx2.unbounded_send(RunnerEvent::Event(2)).unwrap();
            assert_eq!(stream.next().await, Some(RunnerEvent::Event(2)));

            // Cancelling the stream.
            assert!(bg.cancel_stream("discovery"));
            assert_eq!(bg.has_stream("discovery"), false);
            assert!(tx2.is_closed());
            assert!(!bg.cancel_stream("discovery"));
            assert_eq!(bg.active_stream_count(), 0);
        });
    }

    #[test]
    fn test_runner_background_spawn_stream_and_cleanup() {
        futures::executor::block_on(async {
            let bg: RunnerBackground<u32> = RunnerBackground::new();
            let stream_data = futures::stream::iter(vec![
                RunnerEvent::Message("from stream".to_string()),
                RunnerEvent::Event(99),
            ]);
            bg.spawn_stream(stream_data);
            assert_eq!(bg.active_stream_count(), 1);

            let stream = bg.event_stream();
            futures::pin_mut!(stream);

            assert_eq!(stream.next().await, Some(RunnerEvent::Message("from stream".to_string())));
            assert_eq!(stream.next().await, Some(RunnerEvent::Event(99)));

            // Polling again will observe the stream returned None and clean it
            // up.
            let mut cx = std::task::Context::from_waker(futures::task::noop_waker_ref());
            assert!(stream.as_mut().poll_next(&mut cx).is_pending());
            assert_eq!(bg.active_stream_count(), 0);
        });
    }

    #[test]
    fn test_runner_background_waker_waking() {
        let bg: RunnerBackground<u32> = RunnerBackground::new();
        let bg_clone = bg.clone();
        let (polled_tx, polled_rx) = futures::channel::oneshot::channel();

        let handle = std::thread::spawn(move || {
            futures::executor::block_on(polled_rx).unwrap();
            bg_clone.println("woken up");
            bg_clone.send(42);
        });

        futures::executor::block_on(async {
            let stream = bg.event_stream();
            futures::pin_mut!(stream);
            let mut polled_tx = Some(polled_tx);
            let first = futures::future::poll_fn(|cx| {
                let res = stream.as_mut().poll_next(cx);
                if let Some(tx) = polled_tx.take() {
                    assert!(res.is_pending());
                    tx.send(()).unwrap();
                }
                res
            })
            .await;
            assert_eq!(first, Some(RunnerEvent::Message("woken up".to_string())));
            assert_eq!(stream.next().await, Some(RunnerEvent::Event(42)));
        });

        handle.join().unwrap();
    }

    #[test]
    fn test_debug_harness() {
        gen_commandset! {
            HarnessCmd {
                Greet = ("greet", [], ["name"], "Greet a user"),
                Trigger = ("trigger", [], [], "Trigger background event"),
            }
        }

        struct HarnessRunner {
            bg: RunnerBackground<String>,
        }

        impl CommandRunner for HarnessRunner {
            type Set = HarnessCmd;
            type Error = std::io::Error;
            type Event = String;

            fn run_command(
                &self,
                cmd: Self::Set,
                args: Vec<String>,
            ) -> impl futures::Future<Output = Result<(), Self::Error>> {
                match cmd {
                    HarnessCmd::Greet => {
                        let name = args.first().cloned().unwrap_or_else(|| "world".to_string());
                        self.bg.println(format!("Hello, {}!", name));
                    }
                    HarnessCmd::Trigger => {
                        self.bg.send("event_fired".to_string());
                    }
                }
                futures::future::ready(Ok(()))
            }

            fn event_stream(&self) -> impl Stream<Item = RunnerEvent<Self::Event>> + '_ {
                self.bg.event_stream()
            }
        }

        let runner = HarnessRunner { bg: RunnerBackground::new() };
        let harness = DebugHarness::new(runner);

        futures::executor::block_on(async {
            // Test run_command_collecting
            let (res, events) =
                harness.run_command_collecting(HarnessCmd::Greet, vec!["Alice".to_string()]).await;
            assert!(res.is_ok());
            assert_eq!(events, vec![RunnerEvent::Message("Hello, Alice!".to_string())]);

            // Test drive_with with Trigger
            let mut messages = Vec::new();
            let mut domain_events = Vec::new();
            harness
                .drive_with(
                    harness.run(HarnessCmd::Trigger, vec![]),
                    |msg| messages.push(msg),
                    |evt| domain_events.push(evt),
                )
                .await
                .unwrap();

            assert!(messages.is_empty());
            assert_eq!(domain_events, vec!["event_fired".to_string()]);
        });
    }

    #[test]
    fn test_debug_harness_terminating_stream() {
        gen_commandset! {
            FiniteCmd {
                Action = ("action", [], [], "Finite action"),
            }
        }

        struct FiniteStreamRunner {
            stream_done_tx: std::sync::Mutex<Option<futures::channel::oneshot::Sender<()>>>,
        }
        impl CommandRunner for FiniteStreamRunner {
            type Set = FiniteCmd;
            type Error = std::io::Error;
            type Event = u32;

            fn run_command(
                &self,
                _cmd: Self::Set,
                _args: Vec<String>,
            ) -> impl futures::Future<Output = Result<(), Self::Error>> {
                futures::future::ready(Ok(()))
            }

            fn event_stream(&self) -> impl Stream<Item = RunnerEvent<Self::Event>> + '_ {
                let mut done_tx = self.stream_done_tx.lock().unwrap().take();
                futures::stream::iter(vec![
                    RunnerEvent::Message("finite msg".to_string()),
                    RunnerEvent::Event(42),
                ])
                .chain(futures::stream::poll_fn(move |_| {
                    if let Some(tx) = done_tx.take() {
                        let _ = tx.send(());
                    }
                    Poll::Ready(None)
                }))
            }
        }

        let (stream_done_tx, stream_done_rx) = futures::channel::oneshot::channel::<()>();
        let harness = DebugHarness::new(FiniteStreamRunner {
            stream_done_tx: std::sync::Mutex::new(Some(stream_done_tx)),
        });
        futures::executor::block_on(async {
            let (tx, rx) = futures::channel::oneshot::channel::<()>();
            let handle = std::thread::spawn(move || {
                futures::executor::block_on(stream_done_rx).unwrap();
                let _ = tx.send(());
            });

            // The stream terminates after 2 items while rx is still pending.
            // run_collecting_events should not busy-loop and should cleanly
            // complete when rx resolves.
            let (output, events) = harness.run_collecting_events(rx).await;
            assert!(output.is_ok());
            assert_eq!(
                events,
                vec![RunnerEvent::Message("finite msg".to_string()), RunnerEvent::Event(42),]
            );
            handle.join().unwrap();
        });
    }

    #[test]
    fn test_runner_background_stream_static() {
        let bg: RunnerBackground<u32> = RunnerBackground::new();
        bg.send(77);
        let stream = bg.event_stream();

        fn assert_static<T: 'static>(_: &T) {}
        assert_static(&stream);

        futures::executor::block_on(async {
            futures::pin_mut!(stream);
            assert_eq!(stream.next().await, Some(RunnerEvent::Event(77)));
        });
    }
}
