// Copyright 2020 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, Context as _, Error};
use fidl::endpoints::create_endpoints;
use fidl_fuchsia_factory_lowpan::{FactoryDeviceMarker, FactoryDeviceProxy, FactoryLookupMarker};
use fidl_fuchsia_lowpan_device::{
    DeviceExtraMarker, DeviceExtraProxy, DeviceMarker, DeviceProxy, LookupMarker, LookupProxy,
    Protocols,
};
use fidl_fuchsia_lowpan_test::{DeviceTestMarker, DeviceTestProxy};
use fuchsia_component::client::connect_to_service;
use futures::FutureExt;

/// This struct contains all of the transient state that can
/// be kept between invocations of commands when `lowpanctl` is
/// invoked in interactive mode. For single command execution
/// it is set up once and then discarded.
pub struct LowpanContext {
    pub lookup: LookupProxy,
    pub device_name: String,
}

impl LowpanContext {
    const DEFAULT_DEVICE_NAME: &'static str = "lowpan0";

    pub fn new(device_name: Option<String>) -> Result<LowpanContext, Error> {
        let lookup = connect_to_service::<LookupMarker>()
            .context("Failed to connect to Lowpan Lookup service")?;

        Ok(LowpanContext {
            lookup,
            device_name: device_name
                .clone()
                .unwrap_or(LowpanContext::DEFAULT_DEVICE_NAME.to_string()),
        })
    }

    /// Returns the default DeviceProxy.
    pub async fn get_default_device(&self) -> Result<DeviceProxy, Error> {
        let lookup = &self.lookup;

        let (client, server) = create_endpoints::<DeviceMarker>()?;

        lookup
            .lookup_device(
                &self.device_name,
                Protocols {
                    device: Some(server),
                    device_extra: None,
                    device_test: None,
                    ..Protocols::EMPTY
                },
            )
            .map(|x| match x {
                Ok(Ok(())) => Ok(()),
                Ok(Err(x)) => Err(format_err!("Service Error: {:?}", x)),
                Err(x) => Err(x.into()),
            })
            .await?;

        client.into_proxy().context("into_proxy() failed")
    }

    /// Returns the default FactoryDeviceProxy.
    pub async fn get_default_device_factory(&self) -> Result<FactoryDeviceProxy, Error> {
        let lookup = connect_to_service::<FactoryLookupMarker>()
            .context("Failed to connect to Lowpan FactoryLookup service")?;

        let (client, server) = create_endpoints::<FactoryDeviceMarker>()?;

        lookup
            .lookup(&self.device_name, server)
            .map(|x| match x {
                Ok(Ok(())) => Ok(()),
                Ok(Err(x)) => Err(format_err!("Service Error: {:?}", x)),
                Err(x) => Err(x.into()),
            })
            .await
            .context(format!("Unable to find {:?}", &self.device_name))?;

        client.into_proxy().context("into_proxy() failed")
    }

    /// Returns the default DeviceProxy, DeviceExtraProxy and DeviceTestProxy.
    pub async fn get_default_device_proxies(
        &self,
    ) -> Result<(DeviceProxy, DeviceExtraProxy, DeviceTestProxy), Error> {
        let lookup = &self.lookup;

        let (client, server) = create_endpoints::<DeviceMarker>()?;
        let (client_extra, server_extra) = create_endpoints::<DeviceExtraMarker>()?;
        let (client_test, server_test) = create_endpoints::<DeviceTestMarker>()?;

        lookup
            .lookup_device(
                &self.device_name,
                Protocols {
                    device: Some(server),
                    device_extra: Some(server_extra),
                    device_test: Some(server_test),
                    ..Protocols::EMPTY
                },
            )
            .map(|x| match x {
                Ok(Ok(())) => Ok(()),
                Ok(Err(x)) => Err(format_err!("Service Error: {:?}", x)),
                Err(x) => Err(x.into()),
            })
            .await?;
        //.context(format!("Unable to find {:?}", &self.device_name))?;

        Ok((
            client.into_proxy().context("into_proxy() failed")?,
            client_extra.into_proxy().context("into_proxy() failed")?,
            client_test.into_proxy().context("into_proxy() failed")?,
        ))
    }
}
