// 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::{PeerId, Uuid};
use bt_gatt::connected_isochronous::{Framing, MaxTransportLatency};
use bt_gatt::test_utils::{FakeServer, FakeServerEvent, FakeTypes};
use bt_gatt::types::Handle;

use futures::channel::mpsc::UnboundedReceiver;
use futures::{Stream, StreamExt};
use std::pin::Pin;
use std::task::{Context, Poll};

use crate::server::AudioStreamControlServiceServer;
use crate::server::ServiceEvent;
use crate::server::{ASCS_SERVICE_ID, ASCS_UUID};
use crate::types::CodecConfiguration;
use crate::*;

#[track_caller]
fn expect_service_event(events: &mut UnboundedReceiver<FakeServerEvent>) -> FakeServerEvent {
    match events.poll_next_unpin(&mut futures_test::task::noop_context()) {
        Poll::Ready(Some(event)) => event,
        x => panic!("Expected fake server event, got {x:?}"),
    }
}

#[test]
fn publishes() {
    let mut ascs_server = std::pin::pin!(AudioStreamControlServiceServer::<FakeTypes>::new(1, 1));

    let (count_waker, woken_count) = futures_test::task::new_count_waker();

    // Polling the server before it's published should result in Poll::Pending
    let poll_result = ascs_server.as_mut().poll_next(&mut Context::from_waker(&count_waker));

    assert!(poll_result.is_pending());
    assert_eq!(woken_count.get(), 0);

    let (fake_server, mut events) = FakeServer::new();

    let result = ascs_server.publish(&fake_server);
    assert!(result.is_ok());

    let already_published = ascs_server.publish(&fake_server);

    assert!(already_published.is_err());

    assert_eq!(woken_count.get(), 1);

    let poll_result = ascs_server.poll_next(&mut Context::from_waker(&count_waker));

    match expect_service_event(&mut events) {
        FakeServerEvent::Published { id: _, definition } => {
            assert_eq!(definition.uuid(), ASCS_UUID);
            assert_eq!(
                definition.characteristics().filter(|c| c.uuid == Uuid::from_u16(0x2BC4)).count(),
                1
            );
            assert_eq!(
                definition.characteristics().filter(|c| c.uuid == Uuid::from_u16(0x2BC5)).count(),
                1
            );
        }
        x => panic!("Expected published event, got {x:?}"),
    };

    // Should still be pending, even though we had some work to do.
    assert!(poll_result.is_pending());
}

fn register_for_notification(fake_server: &mut FakeServer, peer_id: PeerId, handle: Handle) {
    fake_server.incoming_client_configuration(
        peer_id,
        ASCS_SERVICE_ID,
        handle,
        bt_gatt::server::NotificationType::Notify,
    );
}

// A published server with one sink and one source.
fn published_server() -> (
    Pin<Box<AudioStreamControlServiceServer<FakeTypes>>>,
    FakeServer,
    UnboundedReceiver<FakeServerEvent>,
) {
    let mut ascs_server = Box::pin(AudioStreamControlServiceServer::<FakeTypes>::new(1, 1));
    let (mut fake_server, mut events) = FakeServer::new();

    let result = ascs_server.publish(&fake_server);
    assert!(result.is_ok());

    assert!(ascs_server.poll_next_unpin(&mut futures_test::task::noop_context()).is_pending());

    assert!(matches!(expect_service_event(&mut events), FakeServerEvent::Published { .. }));

    for peer_id in [PeerId(1), PeerId(2)] {
        for handle in [Handle(1), Handle(2), Handle(3)] {
            register_for_notification(&mut fake_server, peer_id, handle);
        }
    }

    (ascs_server, fake_server, events)
}

fn poll_server(
    server: &mut Pin<Box<AudioStreamControlServiceServer<FakeTypes>>>,
) -> Poll<Option<core::result::Result<ServiceEvent, Error>>> {
    server.poll_next_unpin(&mut futures_test::task::noop_context())
}

#[test]
fn peers_are_separated() {
    let (mut ascs_server, fake_server, mut server_events) = published_server();

    // Read the sink uuid
    fake_server.incoming_read(PeerId(1), ASCS_SERVICE_ID, Handle(3), 0);
    // Poll the ascs server, should not result in an ASCS event
    assert!(poll_server(&mut ascs_server).is_pending());

    // Should have the response
    let mut peer_one_value;
    match server_events.poll_next_unpin(&mut futures_test::task::noop_context()) {
        Poll::Ready(Some(FakeServerEvent::ReadResponded { service_id, handle: _, value })) => {
            assert_eq!(service_id, ASCS_SERVICE_ID);
            peer_one_value = value.unwrap();
        }
        x => panic!("Expected the read to be responded to got {x:?}"),
    };

    let ase_id = peer_one_value[0];

    // Codec Configure the first peer ase_id
    fake_server.incoming_write(
        PeerId(1),
        ASCS_SERVICE_ID,
        Handle(1),
        0,
        vec![0x01, 0x01, ase_id, 0x01, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00],
    );

    use crate::server::ServiceEvent;
    use crate::types::*;
    // Should have a codec configure event to respond to
    match poll_server(&mut ascs_server) {
        Poll::Ready(Some(Ok(ServiceEvent::CodecConfigure { responder, .. }))) => {
            responder.accept(
                Framing::Unframed,
                vec![Phy::Le1MPhy],
                5,
                std::time::Duration::from_millis(20).try_into().unwrap(),
                PresentationDelayRange::build(0, 500).unwrap(),
            );
        }
        x => panic!("Expected a CodecConfigure, got {x:?}"),
    };

    // Expect the write to be responded to / acknowledged and a notification from
    // the CP handle and the Source ASE
    match expect_service_event(&mut server_events) {
        FakeServerEvent::WriteResponded { value, .. } => assert!(value.is_ok()),
        x => panic!("Expected acknowledge of write, got {x:?}"),
    };
    assert!(poll_server(&mut ascs_server).is_pending());
    match expect_service_event(&mut server_events) {
        FakeServerEvent::Notified { handle, .. } => assert_eq!(Handle(1), handle),
        x => panic!("Expected acknowledge of write, got {x:?}"),
    };
    match expect_service_event(&mut server_events) {
        FakeServerEvent::Notified { peers, handle, value, .. } => {
            assert!(peers.contains(&PeerId(1)));
            assert_eq!(Handle(3), handle);
            // Should be the same ASE_ID
            assert_eq!(value[0], ase_id);
            assert_eq!(value[1], 0x01); // State is CodecConfigured
            peer_one_value = value;
        }
        x => panic!("Expected acknowledge of write, got {x:?}"),
    };

    // Read the sink id from another peer
    fake_server.incoming_read(PeerId(2), ASCS_SERVICE_ID, Handle(3), 0);

    assert!(poll_server(&mut ascs_server).is_pending());
    assert!(poll_server(&mut ascs_server).is_pending());

    let peer_two_value;
    match expect_service_event(&mut server_events) {
        FakeServerEvent::ReadResponded { service_id, handle: _, value } => {
            assert_eq!(service_id, ASCS_SERVICE_ID);
            peer_two_value = value.unwrap();
        }
        x => panic!("Expected the read to be responded to got {x:?}"),
    };

    assert!(peer_one_value[1] != peer_two_value[1]);
}

#[track_caller]
fn expect_control_point_notified(
    ascs_server: &mut Pin<Box<AudioStreamControlServiceServer<FakeTypes>>>,
    server_events: &mut UnboundedReceiver<FakeServerEvent>,
) -> Vec<u8> {
    // Expect the write to be responded to / acknowledged and a notification from
    // the CP handle and the Source ASE
    match expect_service_event(server_events) {
        FakeServerEvent::WriteResponded { value, .. } => assert!(value.is_ok()),
        x => panic!("Expected acknowledge of write, got {x:?}"),
    };
    assert!(poll_server(ascs_server).is_pending());
    match expect_service_event(server_events) {
        FakeServerEvent::Notified { handle, value, peers, .. } => {
            assert!(peers.contains(&PeerId(1)));
            assert_eq!(Handle(1), handle);
            value
        }
        x => panic!("Expected acknowledge of write, got {x:?}"),
    }
}

#[track_caller]
fn find_ase_id(
    ascs_server: &mut Pin<Box<AudioStreamControlServiceServer<FakeTypes>>>,
    fake_server: &FakeServer,
    server_events: &mut UnboundedReceiver<FakeServerEvent>,
    handle: Handle,
) -> u8 {
    // Read the sink uuid
    fake_server.incoming_read(PeerId(1), ASCS_SERVICE_ID, handle, 0);
    // Poll the ascs server, should not result in an ASCS event
    assert!(poll_server(ascs_server).is_pending());

    // Find the AseId
    let sink_value;
    match server_events.poll_next_unpin(&mut futures_test::task::noop_context()) {
        Poll::Ready(Some(FakeServerEvent::ReadResponded { service_id, handle: _, value })) => {
            assert_eq!(service_id, ASCS_SERVICE_ID);
            sink_value = value.unwrap();
        }
        x => panic!("Expected the read to be responded to got {x:?}"),
    };

    let ase_id = sink_value[0];
    // Should start in idle.
    assert_eq!(sink_value[1], 0x00);
    assert_eq!(sink_value.len(), 2);

    ase_id
}

#[track_caller]
fn find_first_ase_id(
    ascs_server: &mut Pin<Box<AudioStreamControlServiceServer<FakeTypes>>>,
    fake_server: &FakeServer,
    server_events: &mut UnboundedReceiver<FakeServerEvent>,
) -> u8 {
    find_ase_id(ascs_server, fake_server, server_events, Handle(3))
}

#[test]
fn invalid_operation() {
    let (mut ascs_server, fake_server, mut server_events) = published_server();

    let ase_id = find_first_ase_id(&mut ascs_server, &fake_server, &mut server_events);

    // Write an operation that is unknown.
    fake_server.incoming_write(
        PeerId(1),
        ASCS_SERVICE_ID,
        Handle(1),
        0,
        vec![0x1f, 0x01, ase_id, 0xC0, 0xDE],
    );

    // Should have nothing to respond to
    match poll_server(&mut ascs_server) {
        Poll::Pending => {}
        x => panic!("Expected to still be pending, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 0xFF (Table 4.7)
    // ASE_ID is 0x00, and Reason should be 0x00
    assert_eq!(cp_value, &[0x1f, 0xFF, 0x00, 0x01, 0x00]);
}

#[test]
fn invalid_length() {
    let (mut ascs_server, fake_server, mut server_events) = published_server();

    let ase_id = find_first_ase_id(&mut ascs_server, &fake_server, &mut server_events);

    // Write an operation that is the wrong length (too short)
    fake_server.incoming_write(
        PeerId(1),
        ASCS_SERVICE_ID,
        Handle(1),
        0,
        vec![0x01, 0x01, ase_id, 0xC0, 0xDE],
    );

    // Should have nothing to respond to
    match poll_server(&mut ascs_server) {
        Poll::Pending => {}
        x => panic!("Expected to still be pending, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 0xFF (Table 4.7)
    // ASE_ID is 0x00, and Reason should be 0x00
    assert_eq!(cp_value, &[0x01, 0xFF, 0x00, 0x02, 0x00]);
}

#[track_caller]
fn assert_handle_value_eq(
    ascs_server: &mut Pin<Box<AudioStreamControlServiceServer<FakeTypes>>>,
    fake_server: &FakeServer,
    events: &mut UnboundedReceiver<FakeServerEvent>,
    handle: Handle,
    expected: &[u8],
) {
    // Read the sink uuid
    fake_server.incoming_read(PeerId(1), ASCS_SERVICE_ID, handle, 0);
    // Poll the ascs server, should not result in an ASCS event
    assert!(poll_server(ascs_server).is_pending());
    let sink_value;
    match events.poll_next_unpin(&mut futures_test::task::noop_context()) {
        Poll::Ready(Some(FakeServerEvent::ReadResponded { service_id, handle: _, value })) => {
            assert_eq!(service_id, ASCS_SERVICE_ID);
            sink_value = value.unwrap();
        }
        x => panic!("Expected the read to be responded to got {x:?}"),
    };

    assert_eq!(sink_value, expected);
}

#[rustfmt::skip]
fn build_codec_configure(ase_id: u8) -> Vec<u8> {
    // Balanced Latency, 1m phy, LC3 codec (no company / company codecid): ltv (xx
    // bytes), 48khz, frame_duration 10ms, stereo audio channels,
    vec![
        0x01, 0x01, ase_id, 0x02, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00,
        0x10, // 16 bytes
        0x02, 0x01, 0x08, // 48khz
        0x02, 0x02, 0x01, // 10ms duration
        0x05, 0x03, 0x00, 0x00, 0x00, 0x03, // FrontLeft + FrontRight
        0x03, 0x04, 0x64, 0x00, // 100 bytes per codec frame
    ]
}

#[test]
fn invalid_ase_ids() {
    let (mut ascs_server, fake_server, mut server_events) = published_server();

    let ase_id = find_first_ase_id(&mut ascs_server, &fake_server, &mut server_events);

    // Try with an invalid ase_id
    let codec_configure_bad_ase_id = build_codec_configure(0x00);

    fake_server.incoming_write(
        PeerId(1),
        ASCS_SERVICE_ID,
        Handle(1),
        0,
        codec_configure_bad_ase_id.clone(),
    );

    // Should have nothing to respond to
    match poll_server(&mut ascs_server) {
        Poll::Pending => {}
        x => panic!("Expected to still be pending, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match (0x01)
    // Number_of_ASEs should be 1
    // ASE_ID is 0x00, and Reason should be 0x03 (invalid ASE ID)
    assert_eq!(cp_value, &[0x01, 0x01, 0x00, 0x03, 0x00]);

    // Try with one valid and one invalid
    let mut codec_configure_two_ase_ids_one_bad = build_codec_configure(ase_id);
    // Adjust the number of ASEs
    codec_configure_two_ase_ids_one_bad[1] = 0x02;
    // This one has a bad ase_id in it
    // TODO(b/518022833): adjust to find all ASE_IDs and randomly pick a non-used
    // one)
    let bad_ase_id_configure = build_codec_configure(ase_id | 0xF0);
    // Skip the opcode and num of ase_ids in this one
    codec_configure_two_ase_ids_one_bad.extend(&bad_ase_id_configure[2..]);

    fake_server.incoming_write(
        PeerId(1),
        ASCS_SERVICE_ID,
        Handle(1),
        0,
        codec_configure_two_ase_ids_one_bad.clone(),
    );

    // Should have the one valid CodecConfigure to repond to
    match poll_server(&mut ascs_server) {
        Poll::Ready(Some(Ok(ServiceEvent::CodecConfigure {
            configuration:
                CodecConfiguration {
                    target_latency,
                    target_phy,
                    codec_id,
                    codec_specific_configuration,
                    ase_id: configured_ase_id,
                },
            responder,
        }))) => {
            use crate::types::*;
            use bt_common::core::{CodecId, CodingFormat};
            assert_eq!(AseId(ase_id), configured_ase_id);
            assert_eq!(target_latency, TargetLatency::TargetBalanced);
            assert_eq!(target_phy, TargetPhy::Le1MPhy);
            assert_eq!(codec_id, CodecId::Assigned(CodingFormat::Lc3));
            assert_eq!(codec_specific_configuration.len(), 16);
            responder.accept(
                Framing::Unframed,
                vec![Phy::Le1MPhy],
                0x10,
                MaxTransportLatency::try_from(std::time::Duration::from_millis(40)).unwrap(),
                PresentationDelayRange::build(20000, 100000).unwrap(),
            );
        }
        x => panic!("Expected CodecConfigure, got {x:?}"),
    }
    // Then we should be pending.
    match poll_server(&mut ascs_server) {
        Poll::Pending => {}
        x => panic!("Expected to still be pending, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 2
    // ASE_ID should match and succeed, and the other ase_id should have failed.
    assert_eq!(cp_value, &[0x01, 0x02, ase_id | 0xF0, 0x03, 0x00, ase_id, 0x00, 0x00]);
}

#[test]
fn application_rejection() {
    let (mut ascs_server, fake_server, mut server_events) = published_server();

    let ase_id = find_first_ase_id(&mut ascs_server, &fake_server, &mut server_events);

    // Codec configure
    let codec_configure = build_codec_configure(ase_id);
    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, codec_configure.clone());

    // Should have a CodecConfigure to respond to. Let's reject.
    match poll_server(&mut ascs_server) {
        Poll::Ready(Some(Ok(ServiceEvent::CodecConfigure {
            configuration:
                CodecConfiguration {
                    target_latency,
                    target_phy,
                    codec_id,
                    codec_specific_configuration,
                    ase_id,
                },
            responder,
        }))) => {
            use crate::types::*;
            use bt_common::core::{CodecId, CodingFormat};
            assert_eq!(target_latency, TargetLatency::TargetBalanced);
            assert_eq!(target_phy, TargetPhy::Le1MPhy);
            assert_eq!(codec_id, CodecId::Assigned(CodingFormat::Lc3));
            assert_eq!(codec_specific_configuration.len(), 16);
            responder.reject(ResponseCode::InsufficientResources { ase_id });
        }

        x => panic!("Expected CodecConfigure, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 1 should match ASE_ID and response should match.
    assert_eq!(cp_value, &[0x01, 0x01, ase_id, 0x0D, 0x00]);
}

#[test]
fn endpoint_lifecycle_source() {
    let (mut ascs_server, fake_server, mut server_events) = published_server();

    let ase_id = find_first_ase_id(&mut ascs_server, &fake_server, &mut server_events);

    // QosConfigure the ase_id, with CIG 0x01, CIS 0x01, SDU Interval 0x1FF,
    // Unframed, 1m PHY, Max SDU 0x0FFF, RetransmissionNumber 0xFF,
    // Max_Transport_latency max (0x0FA0), and 30ms (0x007530)
    let qos_configure = vec![
        0x02, 0x01, ase_id, 0x01, 0x01, 0x00, 0xFF, 0x01, 0x00, 0x01, 0xFF, 0x0F, 0xFF, 0xA0, 0x0F,
        0x30, 0x75, 0x00,
    ];
    // Can't transition to QoS without CodecConfigure first
    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, qos_configure.clone());

    // Should have nothing to respond to
    match poll_server(&mut ascs_server) {
        Poll::Pending => {}
        x => panic!("Expected to still be pending, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 1
    // ASE_ID is 0x00, and Reason should be 0x04 (invalid state machine transition)
    assert_eq!(cp_value, &[0x02, 0x01, ase_id, 0x04, 0x00]);

    // And the ASE should still be in idle.
    assert_handle_value_eq(
        &mut ascs_server,
        &fake_server,
        &mut server_events,
        Handle(3),
        &[ase_id, 0x00],
    );

    // Go to CodecConfigure
    let codec_configure = build_codec_configure(ase_id);

    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, codec_configure.clone());

    // Should have a CodecConfigure to respond to.
    match poll_server(&mut ascs_server) {
        Poll::Ready(Some(Ok(ServiceEvent::CodecConfigure {
            configuration:
                CodecConfiguration {
                    target_latency,
                    target_phy,
                    codec_id,
                    codec_specific_configuration,
                    ..
                },
            responder,
        }))) => {
            use crate::types::*;
            use bt_common::core::{CodecId, CodingFormat};
            assert_eq!(target_latency, TargetLatency::TargetBalanced);
            assert_eq!(target_phy, TargetPhy::Le1MPhy);
            assert_eq!(codec_id, CodecId::Assigned(CodingFormat::Lc3));
            assert_eq!(codec_specific_configuration.len(), 16);
            responder.accept(
                Framing::Unframed,
                vec![Phy::Le1MPhy],
                0x10,
                MaxTransportLatency::try_from(std::time::Duration::from_millis(40)).unwrap(),
                PresentationDelayRange::build(20000, 100000).unwrap(),
            );
        }

        x => panic!("Expected CodecConfigure, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
    assert_eq!(cp_value, &[0x01, 0x01, ase_id, 0x00, 0x00]);

    // And the ASE should be configured and notified
    match expect_service_event(&mut server_events) {
        FakeServerEvent::Notified { handle, value, peers, .. } => {
            assert!(peers.contains(&PeerId(1)));
            assert_eq!(Handle(3), handle);
            assert_eq!(value[0], ase_id);
            assert_eq!(value[1], 0x01); // Configured state
            assert_eq!(value.len(), 2 + 23 + usize::from(value[24]))
            // state length should be 2 (static) + 24
            // (configured state) + len of codec
            // configuration
        }
        x => panic!("Expected Endpoint Notification, got {x:?}"),
    }

    // QoSConfigure
    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, qos_configure.clone());

    // Should have a QosConfigure to respond to.
    match poll_server(&mut ascs_server) {
        Poll::Ready(Some(Ok(ServiceEvent::QosConfigure {
            peer_id,
            target_configuration: _,
            responder,
        }))) => {
            assert_eq!(peer_id, PeerId(1));
            responder.accept();
        }

        x => panic!("Expected QoSConfigure, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
    assert_eq!(cp_value, &[0x02, 0x01, ase_id, 0x00, 0x00]);

    // And the ASE should be configured and notified
    match expect_service_event(&mut server_events) {
        FakeServerEvent::Notified { handle, value, peers, .. } => {
            assert!(peers.contains(&PeerId(1)));
            assert_eq!(Handle(3), handle);
            assert_eq!(value[0], ase_id);
            assert_eq!(value[1], 0x02); // QoS Configured
        }
        x => panic!("Expected Endpoint Notification, got {x:?}"),
    }

    // Enable
    let enable = vec![0x03, 0x01, ase_id, 0x00];
    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, enable.clone());

    // Should have an event o respond to.
    match poll_server(&mut ascs_server) {
        Poll::Ready(Some(Ok(ServiceEvent::Enable {
            ase_id: enabled_ase_id, responder, ..
        }))) => {
            assert_eq!(ase_id, enabled_ase_id.0);
            responder.accept();
        }

        x => panic!("Expected Enable, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
    assert_eq!(cp_value, &[0x03, 0x01, ase_id, 0x00, 0x00]);

    // And the ASE should be configured and notified
    match expect_service_event(&mut server_events) {
        FakeServerEvent::Notified { handle, value, peers, .. } => {
            assert!(peers.contains(&PeerId(1)));
            assert_eq!(Handle(3), handle);
            assert_eq!(value[0], ase_id);
            assert_eq!(value[1], 0x03); // Enabling
        }
        x => panic!("Expected Endpoint Notification, got {x:?}"),
    }

    // Receiver Start Ready -> Streaming
    let receiver_start_ready = vec![0x04, 0x01, ase_id];
    fake_server.incoming_write(
        PeerId(1),
        ASCS_SERVICE_ID,
        Handle(1),
        0,
        receiver_start_ready.clone(),
    );

    // We auto-accept this, so we should not have a response, but do generate an
    // event.
    match poll_server(&mut ascs_server) {
        Poll::Ready(Some(Ok(ServiceEvent::Start {
            peer_id: _,
            ase_id: started_ase_id,
            cis: _,
        }))) => {
            assert_eq!(ase_id, started_ase_id.0);
        }
        x => panic!("Expected Start, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
    assert_eq!(cp_value, &[0x04, 0x01, ase_id, 0x00, 0x00]);

    // And the ASE should be configured and notified
    match expect_service_event(&mut server_events) {
        FakeServerEvent::Notified { handle, value, peers, .. } => {
            assert!(peers.contains(&PeerId(1)));
            assert_eq!(Handle(3), handle);
            assert_eq!(value[0], ase_id);
            assert_eq!(value[1], 0x04); // Streaming
        }
        x => panic!("Expected Endpoint Notification, got {x:?}"),
    }

    // Disable -> Disabling
    let disable = vec![0x05, 0x01, ase_id];
    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, disable.clone());

    // We auto-accept this, so we should not have a event.
    // We also don't generate an event until Receiver Stop Ready
    match poll_server(&mut ascs_server) {
        Poll::Pending => {}
        x => panic!("Expected no event on Disable, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
    assert_eq!(cp_value, &[0x05, 0x01, ase_id, 0x00, 0x00]);

    // And the ASE should be configured and notified
    match expect_service_event(&mut server_events) {
        FakeServerEvent::Notified { handle, value, peers, .. } => {
            assert!(peers.contains(&PeerId(1)));
            assert_eq!(Handle(3), handle);
            assert_eq!(value[0], ase_id);
            assert_eq!(value[1], 0x05); // Disabling
        }
        x => panic!("Expected Endpoint Notification, got {x:?}"),
    }

    // Receiver Stop Ready -> QoSConfigured
    let receiver_stop_ready = vec![0x06, 0x01, ase_id];
    fake_server.incoming_write(
        PeerId(1),
        ASCS_SERVICE_ID,
        Handle(1),
        0,
        receiver_stop_ready.clone(),
    );

    match poll_server(&mut ascs_server) {
        Poll::Ready(Some(Ok(ServiceEvent::Disable {
            peer_id: _,
            ase_id: disabled_ase_id,
            cis: _,
            responder,
        }))) => {
            assert_eq!(ase_id, disabled_ase_id.0);
            responder.accept();
        }
        x => panic!("Expected Disable, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
    assert_eq!(cp_value, &[0x06, 0x01, ase_id, 0x00, 0x00]);

    // And the ASE should be configured and notified
    match expect_service_event(&mut server_events) {
        FakeServerEvent::Notified { handle, value, peers, .. } => {
            assert!(peers.contains(&PeerId(1)));
            assert_eq!(Handle(3), handle);
            assert_eq!(value[0], ase_id);
            assert_eq!(value[1], 0x02); // QosConfigured
        }
        x => panic!("Expected Endpoint Notification, got {x:?}"),
    }

    // Release -> Releasing
    let release = vec![0x08, 0x01, ase_id];
    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, release.clone());

    // We don't expect an event for this (disable has already happened
    match poll_server(&mut ascs_server) {
        Poll::Pending => {}
        x => panic!("Expected no event from release, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
    assert_eq!(cp_value, &[0x08, 0x01, ase_id, 0x00, 0x00]);

    // And the ASE should be configured and notified
    match expect_service_event(&mut server_events) {
        FakeServerEvent::Notified { handle, value, peers, .. } => {
            assert!(peers.contains(&PeerId(1)));
            assert_eq!(Handle(3), handle);
            assert_eq!(value[0], ase_id);
            assert_eq!(value[1], 0x06); // Releasing
        }
        x => panic!("Expected Endpoint Notification, got {x:?}"),
    }

    // TODO(b/518022833): Automated behaviors are not done yet
    // TODO(b/518022833): Test Update Metadata
}

#[test]
fn endpoint_lifecycle_sink() {
    let (mut ascs_server, fake_server, mut server_events) = published_server();

    // Handle 3 is the Sink ASE
    let ase_id = find_ase_id(&mut ascs_server, &fake_server, &mut server_events, Handle(4));

    // QosConfigure the ase_id, with CIG 0x01, CIS 0x01, SDU Interval 0x1FF,
    // Unframed, 1m PHY, Max SDU 0x0FFF, RetransmissionNumber 0xFF,
    // Max_Transport_latency max (0x0FA0), and 30ms (0x007530)
    let qos_configure = vec![
        0x02, 0x01, ase_id, 0x01, 0x01, 0x00, 0xFF, 0x01, 0x00, 0x01, 0xFF, 0x0F, 0xFF, 0xA0, 0x0F,
        0x30, 0x75, 0x00,
    ];
    // Can't transition to QoS without CodecConfigure first
    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, qos_configure.clone());

    // Should have nothing to respond to
    match poll_server(&mut ascs_server) {
        Poll::Pending => {}
        x => panic!("Expected to still be pending, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 1
    // ASE_ID is 0x00, and Reason should be 0x04 (invalid state machine transition)
    assert_eq!(cp_value, &[0x02, 0x01, ase_id, 0x04, 0x00]);

    // And the ASE should still be in idle.
    assert_handle_value_eq(
        &mut ascs_server,
        &fake_server,
        &mut server_events,
        Handle(4),
        &[ase_id, 0x00],
    );

    // Go to CodecConfigure
    let codec_configure = build_codec_configure(ase_id);

    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, codec_configure.clone());

    // Should have a CodecConfigure to respond to.
    match poll_server(&mut ascs_server) {
        Poll::Ready(Some(Ok(ServiceEvent::CodecConfigure {
            configuration:
                CodecConfiguration {
                    target_latency,
                    target_phy,
                    codec_id,
                    codec_specific_configuration,
                    ..
                },
            responder,
        }))) => {
            use crate::types::*;
            use bt_common::core::{CodecId, CodingFormat};
            assert_eq!(target_latency, TargetLatency::TargetBalanced);
            assert_eq!(target_phy, TargetPhy::Le1MPhy);
            assert_eq!(codec_id, CodecId::Assigned(CodingFormat::Lc3));
            assert_eq!(codec_specific_configuration.len(), 16);
            responder.accept(
                Framing::Unframed,
                vec![Phy::Le1MPhy],
                0x10,
                MaxTransportLatency::try_from(std::time::Duration::from_millis(40)).unwrap(),
                PresentationDelayRange::build(20000, 100000).unwrap(),
            );
        }

        x => panic!("Expected CodecConfigure, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
    assert_eq!(cp_value, &[0x01, 0x01, ase_id, 0x00, 0x00]);

    // And the ASE should be configured and notified
    match expect_service_event(&mut server_events) {
        FakeServerEvent::Notified { handle, value, peers, .. } => {
            assert!(peers.contains(&PeerId(1)));
            assert_eq!(Handle(4), handle);
            assert_eq!(value[0], ase_id);
            assert_eq!(value[1], 0x01); // Configured state
            assert_eq!(value.len(), 2 + 23 + usize::from(value[24]))
            // state length should be 2 (static) + 24
            // (configured state) + len of codec
            // configuration
        }
        x => panic!("Expected Endpoint Notification, got {x:?}"),
    }

    // QoSConfigure
    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, qos_configure.clone());

    // Should have a QosConfigure to respond to.
    match poll_server(&mut ascs_server) {
        Poll::Ready(Some(Ok(ServiceEvent::QosConfigure {
            peer_id,
            target_configuration: _,
            responder,
        }))) => {
            assert_eq!(peer_id, PeerId(1));
            responder.accept();
        }

        x => panic!("Expected QoSConfigure, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
    assert_eq!(cp_value, &[0x02, 0x01, ase_id, 0x00, 0x00]);

    // And the ASE should be configured and notified
    match expect_service_event(&mut server_events) {
        FakeServerEvent::Notified { handle, value, peers, .. } => {
            assert!(peers.contains(&PeerId(1)));
            assert_eq!(Handle(4), handle);
            assert_eq!(value[0], ase_id);
            assert_eq!(value[1], 0x02); // QoS Configured
        }
        x => panic!("Expected Endpoint Notification, got {x:?}"),
    }

    // Enable
    let enable = vec![0x03, 0x01, ase_id, 0x00];
    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, enable.clone());

    // Should have an event to respond to.
    match poll_server(&mut ascs_server) {
        Poll::Ready(Some(Ok(ServiceEvent::Enable {
            ase_id: enabled_ase_id, responder, ..
        }))) => {
            assert_eq!(ase_id, enabled_ase_id.0);
            responder.accept();
        }

        x => panic!("Expected Enable, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
    assert_eq!(cp_value, &[0x03, 0x01, ase_id, 0x00, 0x00]);

    // And the ASE should be configured and notified
    match expect_service_event(&mut server_events) {
        FakeServerEvent::Notified { handle, value, peers, .. } => {
            assert!(peers.contains(&PeerId(1)));
            assert_eq!(Handle(4), handle);
            assert_eq!(value[0], ase_id);
            assert_eq!(value[1], 0x03); // Enabling
        }
        x => panic!("Expected Endpoint Notification, got {x:?}"),
    }

    // Receiver Start Ready should not be allowed from the client for a Sink ASE
    let receiver_start_ready = vec![0x04, 0x01, ase_id];
    fake_server.incoming_write(
        PeerId(1),
        ASCS_SERVICE_ID,
        Handle(1),
        0,
        receiver_start_ready.clone(),
    );

    // Should not have an event for the error.
    match poll_server(&mut ascs_server) {
        Poll::Pending => {}
        x => panic!("Expected no event for invalid ReceiverStartReady, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
    assert_eq!(cp_value, &[0x04, 0x01, ase_id, 0x05, 0x00]);

    // TODO: We don't do server-initiated ReceiverStart yet, so we can't proceed to
    // streaming.

    // Disable -> QosConfigured
    let disable = vec![0x05, 0x01, ase_id];
    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, disable.clone());

    // On Sink ASE, we generate the Disable event when Disabling.
    match poll_server(&mut ascs_server) {
        Poll::Ready(Some(Ok(ServiceEvent::Disable {
            peer_id: _,
            ase_id: disabled_ase_id,
            cis: _,
            responder,
        }))) => {
            assert_eq!(ase_id, disabled_ase_id.0);
            responder.accept();
        }
        x => panic!("Expected Disable, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
    assert_eq!(cp_value, &[0x05, 0x01, ase_id, 0x00, 0x00]);

    // And the ASE should be configured and notified
    match expect_service_event(&mut server_events) {
        FakeServerEvent::Notified { handle, value, peers, .. } => {
            assert!(peers.contains(&PeerId(1)));
            assert_eq!(Handle(4), handle);
            assert_eq!(value[0], ase_id);
            assert_eq!(value[1], 0x02); // Automatically went to QoSConfigure
        }
        x => panic!("Expected Endpoint Notification, got {x:?}"),
    }

    // Receiver Stop Ready is not allowed for a Sink ASE
    let receiver_stop_ready = vec![0x06, 0x01, ase_id];
    fake_server.incoming_write(
        PeerId(1),
        ASCS_SERVICE_ID,
        Handle(1),
        0,
        receiver_stop_ready.clone(),
    );

    assert!(poll_server(&mut ascs_server).is_pending());
    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 1 should match ASE_ID and Failure for Invalid ASE
    // State Transition (since we are already in QosCondfiguredj
    assert_eq!(cp_value, &[0x06, 0x01, ase_id, 0x04, 0x00]);

    // Release -> Releasing
    let release = vec![0x08, 0x01, ase_id];
    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, release.clone());

    // We don't expect an event for this (disable has already happened
    match poll_server(&mut ascs_server) {
        Poll::Pending => {}
        x => panic!("Expected no event from release, got {x:?}"),
    };

    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
    // Opcode should match
    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
    assert_eq!(cp_value, &[0x08, 0x01, ase_id, 0x00, 0x00]);

    // And the ASE should be configured and notified
    match expect_service_event(&mut server_events) {
        FakeServerEvent::Notified { handle, value, peers, .. } => {
            assert!(peers.contains(&PeerId(1)));
            assert_eq!(Handle(4), handle);
            assert_eq!(value[0], ase_id);
            assert_eq!(value[1], 0x06); // Releasing
        }
        x => panic!("Expected Endpoint Notification, got {x:?}"),
    }

    // TODO: Automated behaviors are not done yet
    // TODO: Test Update Metadata
}
