// Copyright 2024 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use bt_common::core::CodecId;
use bt_common::debug_command::{CommandRunner, CommandSet};
use bt_common::gen_commandset;
use std::sync::Mutex;

use bt_gatt::connected_isochronous::{CigId, CisId, SduInterval};
use bt_gatt::{client::PeerServiceHandle, Client};

use crate::client::{AudioStreamControlServiceClient, QosConfigurationRequest};
use crate::server::ASCS_UUID;
use crate::types::*;

gen_commandset! {
    AscsCmd {
        Print = ("print", [], [], "Print the current ASCS status and active configuration details"),
        ConfigCodec = ("config-codec", [], ["configs"], "Configure codecs for one or more ASEs. Format for each ASE: <ase_id>,<latency>,<phy>,<codec>"),
        ConfigQos = ("config-qos", [], ["configs"], "Configure QoS for one or more ASEs. Each config is a comma-separated string: <ase_id>,<cig_id>,<cis_id>,<sdu_interval>,<max_sdu>"),
        Enable = ("enable", [], ["ase_ids"], "Enable ASEs (comma-separated)"),
        ReceiverStartReady = ("receiver-start-ready", [], ["ase_ids"], "Signal receiver start ready for source ASEs (comma-separated)"),
        Disable = ("disable", [], ["ase_ids"], "Disable ASEs (comma-separated)"),
        ReceiverStopReady = ("receiver-stop-ready", [], ["ase_ids"], "Signal receiver stop ready for source ASEs (comma-separated)"),
        UpdateMetadata = ("update-metadata", [], ["ase_ids"], "Update metadata for ASEs (comma-separated, empty metadata)"),
        Release = ("release", [], ["ase_ids"], "Release ASEs (comma-separated)"),
    }
}

pub struct AscsDebug<T: bt_gatt::GattTypes> {
    _peer_client: T::Client,
    client: Mutex<Option<AudioStreamControlServiceClient<T>>>,
}

impl<T: bt_gatt::GattTypes> AscsDebug<T>
where
    <T as bt_gatt::GattTypes>::NotificationStream: std::marker::Send,
{
    pub async fn new(client: T::Client) -> Result<Self, Error> {
        let handles = client.find_service(ASCS_UUID).await?;

        let handle = handles.iter().find(|h| h.is_primary()).ok_or_else(|| {
            Error::Gatt(bt_gatt::types::Error::ScanFailed(
                "Primary ASCS service not found".to_string(),
            ))
        })?;

        let service = handle.connect().await?;
        let ascs_client = AudioStreamControlServiceClient::create(service).await?;

        Ok(Self { _peer_client: client, client: Mutex::new(Some(ascs_client)) })
    }
}

fn invalid_input_err(msg: impl Into<String>) -> Error {
    Error::Other(Box::new(std::io::Error::new(std::io::ErrorKind::InvalidInput, msg.into())))
}

fn parse_ase_id(s: &str) -> Result<AseId, Error> {
    let val = s.parse::<u8>().map_err(|_| invalid_input_err("Invalid ASE ID"))?;
    Ok(AseId(val))
}

fn parse_codec_configuration(s: &str) -> Result<CodecConfiguration, Error> {
    let parts: Vec<&str> = s.split(',').collect();
    if parts.len() != 4 {
        return Err(invalid_input_err(
            "Invalid config format. Expected: <ase_id>,<latency>,<phy>,<codec>",
        ));
    }
    let ase_id = parse_ase_id(parts[0])?;
    let target_latency = match parts[1].to_lowercase().as_str() {
        "low" => TargetLatency::TargetLowLatency,
        "balanced" => TargetLatency::TargetBalanced,
        "high" => TargetLatency::TargetHighReliability,
        _ => {
            return Err(invalid_input_err(
                "Invalid target latency. Expected 'low', 'balanced', or 'high'",
            ));
        }
    };
    let target_phy = match parts[2].to_lowercase().as_str() {
        "1m" => TargetPhy::Le1MPhy,
        "2m" => TargetPhy::Le2MPhy,
        "coded" => TargetPhy::LeCodedPhy,
        _ => {
            return Err(invalid_input_err("Invalid target PHY. Expected '1m', '2m', or 'coded'"));
        }
    };
    let codec_id = match parts[3].to_lowercase().as_str() {
        "lc3" => CodecId::Assigned(bt_common::core::CodingFormat::Lc3),
        "cvsd" => CodecId::Assigned(bt_common::core::CodingFormat::Cvsd),
        _ => {
            return Err(invalid_input_err("Invalid codec format. Expected 'lc3' or 'cvsd'"));
        }
    };
    Ok(CodecConfiguration {
        ase_id,
        target_latency,
        target_phy,
        codec_id,
        codec_specific_configuration: vec![],
    })
}

fn parse_qos_configuration(s: &str) -> Result<QosConfigurationRequest, Error> {
    let parts: Vec<&str> = s.split(',').collect();
    if parts.len() != 5 {
        return Err(invalid_input_err(
            "Invalid config format. Expected: <ase_id>,<cig_id>,<cis_id>,<sdu_interval>,<max_sdu>",
        ));
    }
    let ase_id = parse_ase_id(parts[0])?;
    let cig_id =
        CigId::try_from(parts[1].parse::<u8>().map_err(|_| invalid_input_err("Invalid CIG ID"))?)
            .map_err(|_| invalid_input_err("CIG ID out of bounds"))?;
    let cis_id =
        CisId::try_from(parts[2].parse::<u8>().map_err(|_| invalid_input_err("Invalid CIS ID"))?)
            .map_err(|_| invalid_input_err("CIS ID out of bounds"))?;
    let micros = parts[3].parse::<u64>().map_err(|_| invalid_input_err("Invalid SDU interval"))?;
    let sdu_interval = SduInterval::try_from(std::time::Duration::from_micros(micros))
        .map_err(|_| invalid_input_err("SDU interval out of bounds"))?;
    let max_sdu = MaxSdu::try_from(
        parts[4].parse::<u16>().map_err(|_| invalid_input_err("Invalid Max SDU"))?,
    )
    .map_err(|_| invalid_input_err("Max SDU out of bounds"))?;

    Ok(QosConfigurationRequest::Preferred { ase_id, cig_id, cis_id, sdu_interval, max_sdu })
}

fn parse_ase_ids(s: &str) -> Result<Vec<AseId>, Error> {
    if s.is_empty() {
        return Err(invalid_input_err("Empty ASE ID list"));
    }
    s.split(',').map(parse_ase_id).collect()
}

fn parse_single_arg_ase_ids(args: &[String]) -> Result<Vec<AseId>, Error> {
    if args.len() != 1 {
        return Err(invalid_input_err("Expected comma-separated ASE IDs"));
    }
    parse_ase_ids(&args[0])
}

impl<T: bt_gatt::GattTypes> CommandRunner for AscsDebug<T>
where
    <T as bt_gatt::GattTypes>::NotificationStream: std::marker::Send,
{
    type Set = AscsCmd;
    type Error = crate::types::Error;
    type Event = ();

    fn run_command(
        &self,
        cmd: Self::Set,
        args: Vec<String>,
    ) -> impl futures::Future<Output = Result<(), Self::Error>> {
        async move {
            let mut client = {
                let mut lock = self.client.lock().unwrap();
                lock.take().ok_or_else(|| {
                    Error::Other(Box::new(std::io::Error::new(
                        std::io::ErrorKind::NotConnected,
                        "Failed to connect to ASCS service",
                    )))
                })?
            };

            let result: Result<(), Error> = match cmd {
                AscsCmd::Print => {
                    println!("ASCS Status:");
                    println!("-- Sink Endpoints --");
                    for endpoint in client.endpoints.sink_ases() {
                        if let Some(ep) =
                            client.endpoints.lookup_by_ase_id(endpoint).map(|e| &e.endpoint)
                        {
                            println!(
                                "  ASE ID: {:?}, Handle: {:?}, Direction: Sink, State: {:?}\n    Details: {:?}",
                                ep.ase_id, ep.handle, ep.state, ep.additional
                            );
                        }
                    }
                    println!("-- Source Endpoints --");
                    for endpoint in client.endpoints.source_ases() {
                        if let Some(ep) =
                            client.endpoints.lookup_by_ase_id(endpoint).map(|e| &e.endpoint)
                        {
                            println!(
                                "  ASE ID: {:?}, Handle: {:?}, Direction: Source, State: {:?}\n    Details: {:?}",
                                ep.ase_id, ep.handle, ep.state, ep.additional
                            );
                        }
                    }
                    Ok(())
                }
                AscsCmd::ConfigCodec => {
                    let mut configs = Vec::new();
                    for arg in args {
                        configs.push(parse_codec_configuration(&arg)?);
                    }
                    let outcome = client.configure_codec(configs).await?;
                    println!("Codec Configured Outcome: {:?}", outcome);
                    Ok(())
                }
                AscsCmd::ConfigQos => {
                    let mut requests = Vec::new();
                    for arg in args {
                        requests.push(parse_qos_configuration(&arg)?);
                    }
                    let outcome = client.configure_qos(requests).await?;
                    println!("QoS Configured Outcome: {:?}", outcome);
                    Ok(())
                }
                AscsCmd::Enable => {
                    let ase_ids = parse_single_arg_ase_ids(&args)?;
                    let requests = ase_ids
                        .into_iter()
                        .map(|ase_id| AseIdWithMetadata { ase_id, metadata: vec![] })
                        .collect();
                    let outcome = client.enable(requests).await?;
                    println!("Enable Outcome: {:?}", outcome);
                    Ok(())
                }
                AscsCmd::ReceiverStartReady => {
                    let ase_ids = parse_single_arg_ase_ids(&args)?;
                    let outcome = client.receiver_start_ready(ase_ids).await?;
                    println!("Receiver Start Ready Outcome: {:?}", outcome);
                    Ok(())
                }
                AscsCmd::Disable => {
                    let ase_ids = parse_single_arg_ase_ids(&args)?;
                    let outcome = client.disable(ase_ids).await?;
                    println!("Disable Outcome: {:?}", outcome);
                    Ok(())
                }
                AscsCmd::ReceiverStopReady => {
                    let ase_ids = parse_single_arg_ase_ids(&args)?;
                    let outcome = client.receiver_stop_ready(ase_ids).await?;
                    println!("Receiver Stop Ready Outcome: {:?}", outcome);
                    Ok(())
                }
                AscsCmd::UpdateMetadata => {
                    let ase_ids = parse_single_arg_ase_ids(&args)?;
                    let requests = ase_ids
                        .into_iter()
                        .map(|ase_id| AseIdWithMetadata { ase_id, metadata: vec![] })
                        .collect();
                    let outcome = client.update_metadata(requests).await?;
                    println!("Update Metadata Outcome: {:?}", outcome);
                    Ok(())
                }
                AscsCmd::Release => {
                    let ase_ids = parse_single_arg_ase_ids(&args)?;
                    let outcome = client.release(ase_ids).await?;
                    println!("Release Outcome: {:?}", outcome);
                    Ok(())
                }
            };

            *self.client.lock().unwrap() = Some(client);

            result
        }
    }
}

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

    #[test]
    fn test_parse_ase_id() {
        assert_eq!(parse_ase_id("1").unwrap(), AseId(1));
        assert_eq!(parse_ase_id("255").unwrap(), AseId(255));
        assert!(parse_ase_id("").is_err());
        assert!(parse_ase_id("abc").is_err());
        assert!(parse_ase_id("256").is_err());
    }

    #[test]
    fn test_parse_single_arg_ase_ids() {
        assert_eq!(
            parse_single_arg_ase_ids(&[String::from("1,2")]).unwrap(),
            vec![AseId(1), AseId(2)]
        );
        assert!(parse_single_arg_ase_ids(&[]).is_err());
        assert!(parse_single_arg_ase_ids(&[String::from("1"), String::from("2")]).is_err());
    }

    #[test]
    fn test_parse_ase_ids() {
        assert_eq!(parse_ase_ids("1,2,3").unwrap(), vec![AseId(1), AseId(2), AseId(3)]);
        assert_eq!(parse_ase_ids("1").unwrap(), vec![AseId(1)]);
        assert!(parse_ase_ids("").is_err());
        assert!(parse_ase_ids("1,abc").is_err());
    }

    #[test]
    fn test_parse_codec_configuration() {
        let valid = "2,low,2m,lc3";
        let config = parse_codec_configuration(valid).unwrap();
        assert_eq!(config.ase_id, AseId(2));
        assert_eq!(config.target_latency, TargetLatency::TargetLowLatency);
        assert_eq!(config.target_phy, TargetPhy::Le2MPhy);
        assert_eq!(config.codec_id, CodecId::Assigned(bt_common::core::CodingFormat::Lc3));

        let valid_cvsd = "1,balanced,1m,cvsd";
        let config_cvsd = parse_codec_configuration(valid_cvsd).unwrap();
        assert_eq!(config_cvsd.ase_id, AseId(1));
        assert_eq!(config_cvsd.target_latency, TargetLatency::TargetBalanced);
        assert_eq!(config_cvsd.target_phy, TargetPhy::Le1MPhy);
        assert_eq!(config_cvsd.codec_id, CodecId::Assigned(bt_common::core::CodingFormat::Cvsd));

        // missing codec
        assert!(parse_codec_configuration("2,low,2m").is_err());
        // invalid target latency string
        assert!(parse_codec_configuration("2,unknown,2m,lc3").is_err());
        // invalid target PHY string
        assert!(parse_codec_configuration("2,low,9m,lc3").is_err());
        // invalid codec format string
        assert!(parse_codec_configuration("2,low,2m,aac").is_err());
    }

    #[test]
    fn test_parse_qos_configuration() {
        let valid = "1,2,3,10000,120";
        let request = parse_qos_configuration(valid).unwrap();
        match request {
            QosConfigurationRequest::Preferred {
                ase_id,
                cig_id,
                cis_id,
                sdu_interval,
                max_sdu,
            } => {
                assert_eq!(ase_id, AseId(1));
                assert_eq!(cig_id, CigId::try_from(2).unwrap());
                assert_eq!(cis_id, CisId::try_from(3).unwrap());
                assert_eq!(
                    sdu_interval,
                    SduInterval::try_from(std::time::Duration::from_micros(10000)).unwrap()
                );
                assert_eq!(max_sdu, MaxSdu::try_from(120).unwrap());
            }
            _ => panic!("Expected Preferred request"),
        }

        // missing max_sdu
        assert!(parse_qos_configuration("1,2,3,10000").is_err());
        // CIG ID out of bounds
        assert!(parse_qos_configuration("1,255,3,10000,120").is_err());
        // CIS ID out of bounds
        assert!(parse_qos_configuration("1,2,255,10000,120").is_err());
        // SDU interval out of bounds
        assert!(parse_qos_configuration("1,2,3,100000000,120").is_err());
    }
}
