// Copyright 2023 Google LLC
// 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);
}
