// Copyright 2023 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 std::task::Poll;

use assert_matches::assert_matches;
use futures::{Future, FutureExt, StreamExt};

use bt_common::{PeerId, Uuid};

use crate::test_utils::*;
use crate::types::*;
use crate::{central::Filter, client::PeerService, Central};

const TEST_UUID_1: Uuid = Uuid::from_u16(0x1234);
const TEST_UUID_2: Uuid = Uuid::from_u16(0x2345);
const TEST_UUID_3: Uuid = Uuid::from_u16(0x3456);

// Sets up a fake peer service with some characteristics.
fn set_up() -> FakePeerService {
    let mut fake_peer_service = FakePeerService::new();
    fake_peer_service.add_characteristic(
        Characteristic {
            handle: Handle(1),
            uuid: TEST_UUID_1,
            properties: CharacteristicProperties(vec![
                CharacteristicProperty::Broadcast,
                CharacteristicProperty::Notify,
            ]),
            permissions: AttributePermissions::default(),
            descriptors: vec![],
        },
        vec![],
    );
    fake_peer_service.add_characteristic(
        Characteristic {
            handle: Handle(2),
            uuid: TEST_UUID_1,
            properties: CharacteristicProperties(vec![
                CharacteristicProperty::Broadcast,
                CharacteristicProperty::Notify,
            ]),
            permissions: AttributePermissions::default(),
            descriptors: vec![],
        },
        vec![],
    );
    fake_peer_service.add_characteristic(
        Characteristic {
            handle: Handle(3),
            uuid: TEST_UUID_1,
            properties: CharacteristicProperties(vec![
                CharacteristicProperty::Broadcast,
                CharacteristicProperty::Notify,
            ]),
            permissions: AttributePermissions::default(),
            descriptors: vec![],
        },
        vec![],
    );
    fake_peer_service.add_characteristic(
        Characteristic {
            handle: Handle(4),
            uuid: TEST_UUID_2,
            properties: CharacteristicProperties(vec![CharacteristicProperty::Notify]),
            permissions: AttributePermissions::default(),
            descriptors: vec![],
        },
        vec![],
    );
    fake_peer_service.add_characteristic(
        Characteristic {
            handle: Handle(5),
            uuid: TEST_UUID_3,
            properties: CharacteristicProperties(vec![CharacteristicProperty::Broadcast]),
            permissions: AttributePermissions::default(),
            descriptors: vec![],
        },
        vec![],
    );
    fake_peer_service
}

#[test]
fn peer_service_discover_characteristics_works() {
    let mut noop_cx = futures::task::Context::from_waker(futures::task::noop_waker_ref());

    let fake_peer_service = set_up();

    let mut discover_results = fake_peer_service.discover_characteristics(Some(TEST_UUID_1));
    let polled = discover_results.poll_unpin(&mut noop_cx);
    assert_matches!(polled, Poll::Ready(Ok(chars)) => { assert_eq!(chars.len(), 3) });

    let mut discover_results = fake_peer_service.discover_characteristics(Some(TEST_UUID_2));
    let polled = discover_results.poll_unpin(&mut noop_cx);
    assert_matches!(polled, Poll::Ready(Ok(chars)) => { assert_eq!(chars.len(), 1) });

    let mut discover_results =
        fake_peer_service.discover_characteristics(Some(Uuid::from_u16(0xFF22)));
    let polled = discover_results.poll_unpin(&mut noop_cx);
    assert_matches!(polled, Poll::Ready(Ok(chars)) => { assert_eq!(chars.len(), 0) });

    let mut discover_results = fake_peer_service.discover_characteristics(None);
    let polled = discover_results.poll_unpin(&mut noop_cx);
    assert_matches!(polled, Poll::Ready(Ok(chars)) => { assert_eq!(chars.len(), 5) });
}

#[test]
fn peer_service_read_characteristic() {
    let mut noop_cx = futures::task::Context::from_waker(futures::task::noop_waker_ref());

    let mut fake_peer_service = set_up();
    let mut buf = vec![0; 255];

    // For characteristic that was added, value is returned
    let mut read_result = fake_peer_service.read_characteristic(&Handle(0x1), 0, &mut buf[..]);
    let polled: Poll<std::prelude::v1::Result<(usize, bool), Error>> =
        read_result.poll_unpin(&mut noop_cx);
    assert_matches!(polled, Poll::Ready(Ok((len, _))) => { assert_eq!(len, 0) });

    // For characteristic that doesn't exist, fails.
    let mut read_result = fake_peer_service.read_characteristic(&Handle(0xF), 0, &mut buf[..]);
    let polled = read_result.poll_unpin(&mut noop_cx);
    assert_matches!(polled, Poll::Ready(Err(_)));

    // Change the value for characteristic with handle 1.
    fake_peer_service.add_characteristic(
        Characteristic {
            handle: Handle(1),
            uuid: TEST_UUID_1,
            properties: CharacteristicProperties(vec![
                CharacteristicProperty::Broadcast,
                CharacteristicProperty::Notify,
            ]),
            permissions: AttributePermissions::default(),
            descriptors: vec![],
        },
        vec![0, 1, 2, 3],
    );

    // Successfully reads the updated value.
    let mut read_result = fake_peer_service.read_characteristic(&Handle(0x1), 0, &mut buf[..]);
    let polled = read_result.poll_unpin(&mut noop_cx);
    assert_matches!(polled, Poll::Ready(Ok((len, _))) => {
        assert_eq!(len, 4);
        assert_eq!(buf[..len], vec![0,1,2,3]);
    });
}

#[test]
fn peer_service_write_characteristic() {
    let mut noop_cx = futures::task::Context::from_waker(futures::task::noop_waker_ref());

    let mut fake_peer_service: FakePeerService = set_up();

    // Set expected characteristic value before calling `write_characteristic`.
    fake_peer_service.expect_characteristic_value(&Handle(1), vec![0, 1, 2, 3]);
    let mut write_result = fake_peer_service.write_characteristic(
        &Handle(0x1),
        WriteMode::WithoutResponse,
        0,
        vec![0, 1, 2, 3].as_slice(),
    );

    match write_result.poll_unpin(&mut noop_cx) {
        Poll::Ready(Ok(())) => {}
        _ => panic!("expected write to succeed"),
    }
}

#[test]
#[should_panic]
fn peer_service_write_characteristic_fail() {
    let mut noop_cx = futures::task::Context::from_waker(futures::task::noop_waker_ref());

    let fake_peer_service = set_up();

    // Write some random value without calling `expect_characteristic_value` first.
    let mut write_result = fake_peer_service.write_characteristic(
        &Handle(0x1),
        WriteMode::WithoutResponse,
        0,
        vec![13, 14, 15, 16].as_slice(),
    );

    match write_result.poll_unpin(&mut noop_cx) {
        Poll::Ready(Err(_)) => {}
        _ => panic!("expected write to fail"),
    }
}

#[test]
fn peer_service_subsribe() {
    let mut noop_cx = futures::task::Context::from_waker(futures::task::noop_waker_ref());

    let mut fake_peer_service = set_up();
    let mut notification_stream = fake_peer_service.subscribe(&Handle(0x1));

    // Stream is empty unless we add an item through the FakeNotificationStream
    // struct.
    assert!(notification_stream.poll_next_unpin(&mut noop_cx).is_pending());

    // Update the characteristic value so that notification is sent.
    fake_peer_service.add_characteristic(
        Characteristic {
            handle: Handle(1),
            uuid: TEST_UUID_1,
            properties: CharacteristicProperties(vec![
                CharacteristicProperty::Broadcast,
                CharacteristicProperty::Notify,
            ]),
            permissions: AttributePermissions::default(),
            descriptors: vec![],
        },
        vec![0, 1, 2, 3],
    );

    // Stream should be ready.
    let polled = notification_stream.poll_next_unpin(&mut noop_cx);
    assert_matches!(polled, Poll::Ready(Some(Ok(notification))) => {
        assert_eq!(notification.handle, Handle(0x1));
        assert_eq!(notification.value, vec![0,1,2,3]);
        assert_eq!(notification.maybe_truncated, false);
    });

    assert!(notification_stream.poll_next_unpin(&mut noop_cx).is_pending());
}

#[test]
fn central_search_works() {
    let mut noop_cx = futures::task::Context::from_waker(futures::task::noop_waker_ref());
    let central = FakeCentral::default();

    let mut scan_results = central.scan(&[Filter::ServiceUuid(Uuid::from_u16(0x1844)).into()]);

    let polled = scan_results.poll_next_unpin(&mut noop_cx);
    assert_matches!(polled, Poll::Ready(Some(Ok(_))));
}

fn boxed_generic_usage<T: crate::GattTypes>(central: Box<dyn crate::Central<T>>) {
    use crate::client::PeerServiceHandle;

    let mut noop_cx = futures::task::Context::from_waker(futures::task::noop_waker_ref());
    let _stream = central.scan(&[]);
    let connect_fut = central.connect(PeerId(1));

    futures::pin_mut!(connect_fut);
    let Poll::Ready(Ok(client)) = connect_fut.poll(&mut noop_cx) else {
        panic!("Connect should be ready Ok");
    };

    let client_boxed: Box<dyn crate::client::Client<T>> = Box::new(client);

    let find_serv_fut = client_boxed.find_service(Uuid::from_u16(0));

    futures::pin_mut!(find_serv_fut);
    let Poll::Ready(Ok(services)) = find_serv_fut.poll(&mut noop_cx) else {
        panic!("Expected services future to resolve");
    };

    assert_eq!(services.len(), 1);

    let connect_service_fut = services[0].connect();

    futures::pin_mut!(connect_service_fut);
    let Poll::Ready(Ok(service)) = connect_service_fut.poll(&mut noop_cx) else {
        panic!("Expected service to connect");
    };

    let _service_box: Box<dyn crate::client::PeerService<T>> = Box::new(service);
}

#[test]
fn central_dynamic_usage() {
    let central: Box<dyn crate::Central<FakeTypes>> = Box::new(FakeCentral::default());

    boxed_generic_usage(central);
}
