// 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::channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender};
use futures::{Future, Stream};
use futures::future::{Ready, ready};
use parking_lot::Mutex;
use std::collections::HashMap;
use std::task::Poll;
use std::sync::Arc;

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

#[derive(Default)]
struct FakePeerServiceInner {
    // Notifier that's used to send out notification.
    notifiers: HashMap<Handle, UnboundedSender<Result<CharacteristicNotification>>>,

    // Characteristics to return when `read_characteristic` and `discover_characteristics` are called.
    characteristics: HashMap<Handle, (Characteristic, Vec<u8>)>,
}

#[derive(Clone)]
pub struct FakePeerService {
    inner: Arc<Mutex<FakePeerServiceInner>>,
}

impl FakePeerService {
    pub fn new() -> Self {
        Self { inner: Arc::new(Mutex::new(Default::default())) }
    }

    // Adds a characteristic so that it can be returned when discover/read method is
    // called.
    // Also triggers sending a characteristic value change notification to be sent.
    pub fn add_characteristic(&mut self, char: Characteristic, value: Vec<u8>) {
        let mut lock = self.inner.lock();
        let handle = char.handle;
        lock.characteristics.insert(handle, (char, value.clone()));
        if let Some(notifier) = lock.notifiers.get_mut(&handle) {
            notifier.unbounded_send(Ok(CharacteristicNotification { handle, value, maybe_truncated: false })).expect("should succeed");
        }
    }
}

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

    fn discover_characteristics(&self, uuid: Option<Uuid>) -> Self::CharacteristicsFut {
        let lock = self.inner.lock();
        let mut result = Vec::new();
        for (_handle, (char, _value))in &lock.characteristics {
            match uuid {
                Some(uuid) if uuid == char.uuid => result.push(char.clone()),
                None => result.push(char.clone()),
                _ => {},
            }
        }
        ready(Ok(result))
    }

    fn read_characteristic<'a>(
        &self,
        handle: &Handle,
        _offset: u16,
        buf: &'a mut [u8],
    ) -> Self::ReadFut<'a> {
        let read_characteristics = &(*self.inner.lock()).characteristics;
        let Some((_, value)) = read_characteristics.get(handle) else {
            return ready(Err(Error::Gatt(GattError::InvalidHandle)));
        };
        buf[..value.len()].copy_from_slice(value.as_slice());
        ready(Ok((value.len(), false)))
    }

    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 {
        let (sender, receiver) = unbounded();
        (*self.inner.lock()).notifiers.insert(*handle, sender);
        receiver
    }
}

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!()
    }
}
