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

use bt_common::debug_command::CommandRunner;
use bt_common::debug_command::CommandSet;
use bt_common::gen_commandset;

use bt_gatt::{
    client::{PeerService, PeerServiceHandle},
    Client,
};

use crate::*;

gen_commandset! {
    PacsCmd {
        Print = ("print", [], [], "Print the current PACS status"),
    }
}

pub struct PacsDebug<T: bt_gatt::GattTypes> {
    client: T::Client,
}

impl<T: bt_gatt::GattTypes> PacsDebug<T> {
    pub fn new(client: T::Client) -> Self {
        Self { client }
    }
}

impl<T: bt_gatt::GattTypes> CommandRunner for PacsDebug<T> {
    type Set = PacsCmd;
    type Error = bt_gatt::types::Error;
    type Event = ();

    fn run_command(
        &self,
        _cmd: Self::Set,
        _args: Vec<String>,
    ) -> impl futures::Future<Output = Result<(), Self::Error>> {
        async {
            // Since there is only one command, Print, we just print
            // all the characteristics that are at the remote PACS server.
            let handles = self.client.find_service(PACS_UUID).await?;
            for handle in handles {
                let service = handle.connect().await?;

                let chrs = service.discover_characteristics(None).await?;
                for chr in chrs {
                    match chr.uuid {
                        SourcePac::UUID => {
                            let source_pac = SourcePac::try_read::<T>(chr, &service).await?;
                            println!("{source_pac:?}");
                        }
                        SinkPac::UUID => {
                            let sink_pac = SinkPac::try_read::<T>(chr, &service).await?;
                            println!("{sink_pac:?}");
                        }
                        SinkAudioLocations::UUID => {
                            let locations =
                                SinkAudioLocations::try_read::<T>(chr, &service).await?;
                            println!("{locations:?}");
                        }
                        SourceAudioLocations::UUID => {
                            let locations =
                                SourceAudioLocations::try_read::<T>(chr, &service).await?;
                            println!("{locations:?}");
                        }
                        AvailableAudioContexts::UUID => {
                            let contexts =
                                AvailableAudioContexts::try_read::<T>(chr, &service).await?;
                            println!("{contexts:?}");
                        }
                        SupportedAudioContexts::UUID => {
                            let contexts =
                                SupportedAudioContexts::try_read::<T>(chr, &service).await?;
                            println!("{contexts:?}");
                        }
                        _x => println!("Unrecognized Chr {}", chr.uuid.recognize()),
                    }
                }
            }
            Ok::<(), bt_gatt::types::Error>(())
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use bt_common::debug_command::CliCommand;
    use bt_gatt::test_utils::{FakeClient, FakeTypes};
    use log::LevelFilter;

    fn setup_fake_pacs_debug() -> PacsDebug<FakeTypes> {
        PacsDebug::new(FakeClient::new())
    }

    #[test]
    fn verbosity_controls_and_flags() {
        let debug = setup_fake_pacs_debug();

        log::set_max_level(LevelFilter::Info);

        // Verbose with no args displays current verbosity without changing it
        let res = futures::executor::block_on(debug.run(CliCommand::Verbose, vec![]));
        assert!(res.is_ok());
        assert_eq!(log::max_level(), LevelFilter::Info);

        // Update verbosity to Debug
        let res =
            futures::executor::block_on(debug.run(CliCommand::Verbose, vec!["debug".to_string()]));
        assert!(res.is_ok());
        assert_eq!(log::max_level(), LevelFilter::Debug);

        // Update verbosity to Trace
        let res =
            futures::executor::block_on(debug.run(CliCommand::Verbose, vec!["trace".to_string()]));
        assert!(res.is_ok());
        assert_eq!(log::max_level(), LevelFilter::Trace);

        // Update verbosity to Off
        let res =
            futures::executor::block_on(debug.run(CliCommand::Verbose, vec!["off".to_string()]));
        assert!(res.is_ok());
        assert_eq!(log::max_level(), LevelFilter::Off);

        // Invalid level does not change verbosity
        let res = futures::executor::block_on(
            debug.run(CliCommand::Verbose, vec!["invalid_level".to_string()]),
        );
        assert!(res.is_ok());
        assert_eq!(log::max_level(), LevelFilter::Off);

        // Reset back to Info for scoped flags testing
        log::set_max_level(LevelFilter::Info);

        // Executing Print with -v flag:
        // 1. debug.run() strips the flag before run_command.
        // 2. Temporarily elevates max log level during execution.
        // 3. Executes successfully.
        let res = futures::executor::block_on(debug.run(PacsCmd::Print, vec!["-v".to_string()]));
        assert!(res.is_ok());

        // Persistent verbosity remains Info after scoped execution completes
        assert_eq!(log::max_level(), LevelFilter::Info);

        // Executing Print with -vv flag elevates to Trace
        let res = futures::executor::block_on(debug.run(PacsCmd::Print, vec!["-vv".to_string()]));
        assert!(res.is_ok());
        assert_eq!(log::max_level(), LevelFilter::Info);
    }
}
