// 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;

    fn run(
        &self,
        cmd: Self::Set,
        args: Vec<String>,
    ) -> impl futures::Future<Output = Result<(), impl std::error::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());
    }
}
