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

// TODO(armansito): Remove this once a server channel can be killed using a Controller
#![allow(unreachable_code)]

use bt::error::Error as BTError;
use common::gatt::start_gatt_loop;
use failure::Error;
use fidl::endpoints2;
use fidl_ble::{CentralEvent, CentralProxy, RemoteDevice};
use futures::future;
use futures::future::Either::{Left, Right};
use futures::prelude::*;
use parking_lot::RwLock;
use std::fmt;
use std::process::exit;
use std::string::String;
use std::sync::Arc;

type CentralStatePtr = Arc<RwLock<CentralState>>;

pub struct CentralState {
    // If true, stop scanning and close the delegate handle after the first scan result.
    pub scan_once: bool,

    // If true, attempt to connect to the first scan result.
    pub connect: bool,

    // The proxy that we use to perform LE central requests.
    svc: CentralProxy,
}

impl CentralState {
    pub fn new(proxy: CentralProxy) -> CentralStatePtr {
        Arc::new(RwLock::new(CentralState {
            scan_once: false,
            connect: false,
            svc: proxy,
        }))
    }

    pub fn get_svc(&self) -> &CentralProxy {
        &self.svc
    }
}

pub fn listen_central_events(
    state: CentralStatePtr,
) -> impl Future<Item = (), Error = Never> + Send {
    let evt_stream = state.read().get_svc().take_event_stream();
    evt_stream
        .for_each(move |evt| {
            match evt {
                CentralEvent::OnScanStateChanged { scanning } => {
                    eprintln!("  scan state changed: {}", scanning);
                    Left(future::ok(()))
                }
                CentralEvent::OnDeviceDiscovered { device } => {
                    let id = device.identifier.clone();
                    let connectable = device.connectable;

                    eprintln!(" {}", RemoteDeviceWrapper(device));

                    let central = state.read();
                    if !central.scan_once && !central.connect {
                        return Left(future::ok(()));
                    }

                    // Stop scanning.
                    if let Err(e) = central.svc.stop_scan() {
                        eprintln!("request to stop scan failed: {}", e);
                        // TODO(armansito): kill the channel here instead
                        exit(0);
                        Left(future::ok(()))
                    } else if central.connect && connectable {
                        Right(connect_peripheral(state.clone(), id).recover(|_| {
                            // TODO(armansito): kill the channel here instead
                            exit(0);
                            ()
                        }))
                    } else {
                        // TODO(armansito): kill the channel here instead
                        exit(0);
                        Left(future::ok(()))
                    }
                }
                CentralEvent::OnPeripheralDisconnected { identifier } => {
                    eprintln!("  peer disconnected: {}", identifier);
                    // TODO(armansito): Close the channel here instead
                    exit(0);
                    Left(future::ok(()))
                }
            }
        })
        .map(|_| ())
        .recover(|e| eprintln!("failed to subscribe to BLE Central events: {:?}", e))
}

// Attempts to connect to the peripheral with the given |id| and begins the
// GATT REPL if this succeeds.
fn connect_peripheral(
    state: CentralStatePtr, mut id: String,
) -> impl Future<Item = (), Error = Error> {
    let (proxy, server) = match endpoints2::create_endpoints() {
        Err(_) => {
            return Left(future::err(
                BTError::new("Failed to create Client pair").into(),
            ));
        }
        Ok(res) => res,
    };

    Right(
        state
            .read()
            .svc
            .connect_peripheral(&mut id, server)
            .map_err(|e| {
                BTError::new(&format!("failed to initiate connect request: {}", e)).into()
            })
            .and_then(move |status| match status.error {
                Some(e) => {
                    println!(
                        "  failed to connect to peripheral: {}",
                        match e.description {
                            None => "unknown error",
                            Some(ref msg) => &msg,
                        }
                    );
                    Err(BTError::from(*e).into())
                }
                None => {
                    println!("  device connected: {}", id);
                    Ok(proxy)
                }
            })
            .and_then(|proxy| start_gatt_loop(proxy)),
    )
}

struct RemoteDeviceWrapper(RemoteDevice);

impl fmt::Display for RemoteDeviceWrapper {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let connectable = if self.0.connectable {
            "conn"
        } else {
            "non-conn"
        };

        write!(f, "[device({}), ", connectable)?;

        if let Some(ref rssi) = self.0.rssi {
            write!(f, "rssi: {}, ", rssi.value)?;
        }

        if let Some(ref ad) = self.0.advertising_data {
            if let Some(ref name) = ad.name {
                write!(f, "{}, ", name)?;
            }
        }

        write!(f, "id: {}]", self.0.identifier)
    }
}
