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