// Copyright 2018 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.

#![feature(async_await, await_macro, futures_api)]

use {
    failure::{Error, ResultExt},
    fidl::endpoints::ServiceMarker,
    fidl_fuchsia_bluetooth_bredr::ProfileMarker,
    fidl_fuchsia_bluetooth_control::ControlMarker,
    fidl_fuchsia_bluetooth_gatt::Server_Marker,
    fidl_fuchsia_bluetooth_le::{CentralMarker, PeripheralMarker},
    fidl_fuchsia_bluetooth_snoop::SnoopMarker,
    fuchsia_app::{
        server::ServicesServer,
        client::{connect_to_service, Launcher},
    },
    fuchsia_async as fasync,
    fuchsia_bluetooth::make_clones,
    fuchsia_syslog::{self as syslog, fx_log_info, fx_log_warn},
    futures::TryFutureExt,
    parking_lot::Mutex,
    std::sync::Arc,
};

mod config;

fn main() -> Result<(), Error> {
    syslog::init_with_tags(&["bt-mgr"]).expect("Can't init logger");
    fx_log_info!("Starting bt-mgr...");

    let mut executor = fasync::Executor::new().context("Error creating executor")?;
    let cfg = config::Config::load()?;

    // Start bt-snoop service before anything else.
    if cfg.autostart_snoop() {
        let res = connect_to_service::<SnoopMarker>();
        if let Err(e) = res {
            fx_log_warn!("Failed to start snoop service: {}", e);
        }
    }

    let launcher = Launcher::new()
        .context("Failed to open launcher service")
        .unwrap();
    let btgap = Arc::new(Mutex::new(
        launcher
            .launch(
                String::from("fuchsia-pkg://fuchsia.com/bt-gap#meta/bt-gap.cmx"),
                None,
            )
            .context("Failed to launch bt-gap (bluetooth) service")
            .unwrap(),
    ));

    make_clones!(btgap => btgap_control, btgap_central, btgap_peripheral, btgap_profile, btgap_gatt_server);
    let server = ServicesServer::new()
        .add_service((ControlMarker::NAME, move |chan: fasync::Channel| {
            fx_log_info!("Passing Control Handle to bt-gap");
            let _ = btgap_control
                .lock()
                .pass_to_service(ControlMarker, chan.into());
        }))
        .add_service((CentralMarker::NAME, move |chan: fasync::Channel| {
            fx_log_info!("Passing LE Central Handle to bt-gap");
            let _ = btgap_central
                .lock()
                .pass_to_service(CentralMarker, chan.into());
        }))
        .add_service((PeripheralMarker::NAME, move |chan: fasync::Channel| {
            fx_log_info!("Passing Peripheral Handle to bt-gap");
            let _ = btgap_peripheral
                .lock()
                .pass_to_service(PeripheralMarker, chan.into());
        }))
        .add_service((ProfileMarker::NAME, move |chan: fasync::Channel| {
            fx_log_info!("Passing Profile Handle to bt-gap");
            let _ = btgap_profile
                .lock()
                .pass_to_service(ProfileMarker, chan.into());
        }))
        .add_service((Server_Marker::NAME, move |chan: fasync::Channel| {
            fx_log_info!("Passing GATT Handle to bt-gap");
            let _ = btgap_gatt_server
                .lock()
                .pass_to_service(Server_Marker, chan.into());
        }))
        .start()
        .map_err(|e| e.context("error starting service server"))?;

    let io_config_fut = cfg.set_capabilities();
    executor
        .run_singlethreaded(server.try_join(io_config_fut))
        .context("bt-mgr failed to execute future")
        .map_err(|e| e.into())
        .map(|_| ())
}
