// 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 crate::{central::ScanResult, client::CharacteristicNotification, types::*};

use bt_common::{PeerId, Uuid};
use futures::{future::Ready, stream::Empty, Future, Stream};
use std::task::Poll;

#[derive(Default)]
pub(crate) struct FakeCentral {}

pub(crate) struct FakePeerService {}

impl crate::client::PeerService for FakePeerService {
    type CharacteristicsFut = Ready<Result<Vec<Characteristic>>>;
    type NotificationStream = Empty<Result<CharacteristicNotification>>;
    type ReadFut<'a> = Ready<Result<(usize, bool)>>;
    type WriteFut<'a> = Ready<Result<()>>;

    fn discover_characteristics(&self, _uuid: Option<Uuid>) -> Self::CharacteristicsFut {
        todo!()
    }

    fn read_characteristic<'a>(
        &self,
        _handle: &Handle,
        _offset: u16,
        _buf: &'a mut [u8],
    ) -> Self::ReadFut<'a> {
        todo!()
    }

    fn write_characteristic<'a>(
        &self,
        _handle: &Handle,
        _mode: WriteMode,
        _offset: u16,
        _buf: &'a [u8],
    ) -> Self::WriteFut<'a> {
        todo!()
    }

    fn read_descriptor<'a>(
        &self,
        _handle: &Handle,
        _offset: u16,
        _buf: &'a mut [u8],
    ) -> Self::ReadFut<'a> {
        todo!()
    }

    fn write_descriptor<'a>(
        &self,
        _handle: &Handle,
        _offset: u16,
        _buf: &'a [u8],
    ) -> Self::WriteFut<'a> {
        todo!()
    }

    fn subscribe(&self, _handle: &Handle) -> Self::NotificationStream {
        todo!()
    }
}

pub(crate) struct FakeServiceHandle {}

impl crate::client::PeerServiceHandle for FakeServiceHandle {
    type PeerServiceT = FakePeerService;
    type ConnectFut = Ready<Result<Self::PeerServiceT>>;

    fn uuid(&self) -> Uuid {
        todo!()
    }

    fn is_primary(&self) -> bool {
        todo!()
    }

    fn connect(&self) -> Self::ConnectFut {
        todo!()
    }
}

pub(crate) struct FakeClient {}

impl crate::Client for FakeClient {
    type PeerServiceHandleT = FakeServiceHandle;
    type ServiceResultFut = Ready<Result<Vec<Self::PeerServiceHandleT>>>;

    fn peer_id(&self) -> PeerId {
        todo!()
    }

    fn find_service(&self, _uuid: Uuid) -> Self::ServiceResultFut {
        todo!()
    }
}

pub(crate) struct SingleResultStream {
    result: Option<Result<crate::central::ScanResult>>,
}

impl Stream for SingleResultStream {
    type Item = Result<crate::central::ScanResult>;

    fn poll_next(
        self: std::pin::Pin<&mut Self>,
        _cx: &mut std::task::Context<'_>,
    ) -> Poll<Option<Self::Item>> {
        if self.result.is_some() {
            Poll::Ready(self.get_mut().result.take())
        } else {
            // Never wake up, as if we never find another result
            Poll::Pending
        }
    }
}

pub(crate) struct ClientConnectFut {}

impl Future for ClientConnectFut {
    type Output = Result<FakeClient>;

    fn poll(
        self: std::pin::Pin<&mut Self>,
        _cx: &mut std::task::Context<'_>,
    ) -> Poll<Self::Output> {
        todo!()
    }
}

impl crate::Central for FakeCentral {
    type ScanResultStream = SingleResultStream;

    type Client = FakeClient;

    type ClientFut = ClientConnectFut;

    fn scan(&self, _filters: &[crate::central::ScanFilter]) -> Self::ScanResultStream {
        SingleResultStream {
            result: Some(Ok(ScanResult {
                id: PeerId(1),
                connectable: true,
                name: crate::central::PeerName::CompleteName("Marie's Pixel 7 Pro".to_owned()),
                advertised: vec![crate::central::AdvertisingDatum::Services(vec![
                    Uuid::from_u16(0x1844),
                ])],
            })),
        }
    }

    fn connect(&self, _peer_id: PeerId) -> Self::ClientFut {
        todo!()
    }
}

#[test]
fn central_search_works() {
    use crate::Central;
    use futures::StreamExt;

    let mut noop_cx = futures::task::Context::from_waker(futures::task::noop_waker_ref());
    use crate::central::Filter;
    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);
    let Poll::Ready(Some(Ok(_scan_result))) = polled else {
        panic!("Expected a ready scan result got {polled:?}");
    };
}
