// 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},
    bt_test_harness::deprecated::control::{
        activate_fake_host, expectation, ControlHarness, ControlState, FAKE_HCI_ADDRESS,
    },
    fidl_fuchsia_bluetooth_test::{AdvertisingData, LowEnergyPeerParameters},
    fuchsia_bluetooth::{
        expectation::{
            asynchronous::{ExpectableExt, ExpectableState, ExpectableStateExt},
            Predicate,
        },
        hci_emulator::Emulator,
        types::Address,
    },
    test_harness::run_suite,
};

use crate::tests::timeout_duration;

async fn test_set_active_host(control: ControlHarness) -> Result<(), Error> {
    let initial_hosts: Vec<String> = control.read().hosts.keys().cloned().collect();
    let initial_hosts_ = initial_hosts.clone();

    let mut fake_hci_0 = Emulator::create_and_publish("bt-hci-integration-control-0").await?;
    let mut fake_hci_1 = Emulator::create_and_publish("bt-hci-integration-control-1").await?;

    let state = control
        .when_satisfied(
            Predicate::<ControlState>::predicate(
                move |control| {
                    let added_fake_hosts = control.hosts.iter().filter(|(id, host)| {
                        host.address == FAKE_HCI_ADDRESS && !initial_hosts_.contains(id)
                    });
                    added_fake_hosts.count() > 1
                },
                "Both Fake Hosts Added",
            ),
            timeout_duration(),
        )
        .await?;

    let fake_hosts: Vec<String> = state
        .hosts
        .iter()
        .filter(|(id, host)| host.address == FAKE_HCI_ADDRESS && !initial_hosts.contains(id))
        .map(|(id, _)| id.clone())
        .collect();

    for host in fake_hosts.iter() {
        let fut = control.aux().set_active_adapter(host);
        fut.await?;
        control
            .when_satisfied(expectation::active_host_is(host.to_string()), timeout_duration())
            .await?;
    }

    fake_hci_0.destroy_and_wait().await?;
    fake_hci_1.destroy_and_wait().await?;

    for host in fake_hosts {
        control.when_satisfied(expectation::host_not_present(host), timeout_duration()).await?;
    }

    Ok(())
}

async fn test_disconnect(control: ControlHarness) -> Result<(), Error> {
    let (_host, mut hci) = activate_fake_host(control.clone(), "bt-hci-integration").await?;

    // Insert a fake peer to test connection and disconnection.
    let peer_address = Address::Random([1, 0, 0, 0, 0, 0]);
    let peer_params = LowEnergyPeerParameters {
        address: Some(peer_address.into()),
        connectable: Some(true),
        advertisement: Some(AdvertisingData {
            data: vec![0x02, 0x01, 0x02], // Flags field set to "general discoverable"
        }),
        scan_response: None,
        ..LowEnergyPeerParameters::EMPTY
    };
    let (_peer, remote) = fidl::endpoints::create_proxy()?;
    let _ = hci
        .emulator()
        .add_low_energy_peer(peer_params, remote)
        .await?
        .map_err(|e| format_err!("Failed to register fake peer: {:#?}", e))?;

    let fut = control.aux().request_discovery(true);
    fut.await?;
    let state = control
        .when_satisfied(
            expectation::peer_with_address(&peer_address.to_string()),
            timeout_duration(),
        )
        .await?;

    // TODO(armansito): Generalize Emulator/Peer state tracking from low_energy_peripheral tests and
    // verify the controller state here.

    // We can safely unwrap here as this is guarded by the previous expectation
    let peer = state.peers.iter().find(|(_, p)| &p.address == &peer_address.to_string()).unwrap().0;

    let fut = control.aux().connect(peer);
    fut.await?;

    control.when_satisfied(expectation::peer_connected(peer, true), timeout_duration()).await?;
    let fut = control.aux().disconnect(peer);
    fut.await?;

    control.when_satisfied(expectation::peer_connected(peer, false), timeout_duration()).await?;

    hci.destroy_and_wait().await?;
    Ok(())
}

/// Run all test cases.
pub fn run_all() -> Result<(), Error> {
    run_suite!("control.Control", [test_set_active_host, test_disconnect])
}
