// Copyright 2019 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 {
    anyhow::{format_err, Error},
    fidl::endpoints::RequestStream,
    fidl_fuchsia_bluetooth_host::{HostControlHandle, HostMarker, HostRequest, HostRequestStream},
    fidl_fuchsia_bluetooth_sys::{HostInfo as FidlHostInfo, TechnologyType},
    fuchsia_bluetooth::{
        inspect::{placeholder_node, Inspectable},
        types::{Address, BondingData, HostInfo, Peer, PeerId},
    },
    futures::{future, join, stream::StreamExt},
    parking_lot::RwLock,
    std::path::PathBuf,
    std::sync::Arc,
};

use crate::{
    host_device::{refresh_host_info, HostDevice, HostListener},
    test::create_fidl_endpoints,
};

// An impl that ignores all events
impl HostListener for () {
    fn on_peer_updated(&mut self, _peer: Peer) {}
    fn on_peer_removed(&mut self, _id: PeerId) {}
    type HostBondFut = future::Ready<Result<(), anyhow::Error>>;
    fn on_new_host_bond(&mut self, _data: BondingData) -> Self::HostBondFut {
        future::ok(())
    }
}

// Create a HostDevice with a fake channel, set local name and check it is updated
#[fuchsia_async::run_singlethreaded(test)]
async fn host_device_set_local_name() -> Result<(), Error> {
    let (client, server) = create_fidl_endpoints::<HostMarker>()?;

    let info = HostInfo {
        id: fidl_fuchsia_bluetooth::Id { value: 1 },
        technology: TechnologyType::DualMode,
        address: Address::Public([0, 0, 0, 0, 0, 0]),
        local_name: None,
        active: false,
        discoverable: false,
        discovering: false,
    };
    let host = Arc::new(RwLock::new(HostDevice::new(
        PathBuf::from("/dev/class/bt-host/test"),
        client,
        Inspectable::new(info.clone(), placeholder_node()),
    )));
    let name = "EXPECTED_NAME".to_string();

    let info = Arc::new(RwLock::new(info));
    let server = Arc::new(RwLock::new(server));

    // Assign a name and verify that that it gets written to the bt-host over FIDL.
    let set_name = host.write().set_name(name.clone());
    let expect_fidl = expect_call(server.clone(), |_, e| match e {
        HostRequest::SetLocalName { local_name, responder } => {
            info.write().local_name = Some(local_name);
            responder.send(&mut Ok(()))?;
            Ok(())
        }
        _ => Err(format_err!("Unexpected!")),
    });
    let (set_name_result, expect_result) = join!(set_name, expect_fidl);
    let _ = set_name_result.expect("failed to set name");
    let _ = expect_result.expect("FIDL result unsatisfied");

    let refresh = refresh_host_info(host.clone());
    let expect_fidl = expect_call(server.clone(), |_, e| match e {
        HostRequest::WatchState { responder } => {
            responder.send(FidlHostInfo::from(info.read().clone()))?;
            Ok(())
        }
        _ => Err(format_err!("Unexpected!")),
    });
    let (refresh_result, expect_result) = join!(refresh, expect_fidl);
    let _ = refresh_result.expect("did not receive HostInfo update");
    let _ = expect_result.expect("FIDL result unsatisfied");

    let host_name = host.read().get_info().local_name.clone();
    println!("name: {:?}", host_name);
    assert!(host_name == Some(name));
    Ok(())
}

// TODO(39373): Add host.fidl emulation to bt-fidl-mocks and use that instead.
async fn expect_call<F>(stream: Arc<RwLock<HostRequestStream>>, f: F) -> Result<(), Error>
where
    F: FnOnce(Arc<HostControlHandle>, HostRequest) -> Result<(), Error>,
{
    let control_handle = Arc::new(stream.read().control_handle());
    let mut stream = stream.write();
    if let Some(event) = stream.next().await {
        let event = event?;
        f(control_handle, event)
    } else {
        Err(format_err!("No event received"))
    }
}
