// 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 crate::clock;
use crate::event::{Event, Publisher};
use crate::message::base::MessengerType;
use crate::service;
use anyhow::{format_err, Error};
use fidl::endpoints::{DiscoverableProtocolMarker, ProtocolMarker, Proxy};
use fuchsia_async as fasync;
use fuchsia_component::client::{connect_to_protocol, connect_to_protocol_at_path};
use fuchsia_zircon as zx;
use futures::future::{BoxFuture, OptionFuture};
use glob::glob;
use std::borrow::Cow;
use std::fmt::Debug;
use std::future::Future;

pub type GenerateService =
    Box<dyn Fn(&str, zx::Channel) -> BoxFuture<'static, Result<(), Error>> + Send + Sync>;

/// A wrapper around service operations, allowing redirection to a nested
/// environment.
pub struct ServiceContext {
    generate_service: Option<GenerateService>,
    delegate: Option<service::message::Delegate>,
}

impl ServiceContext {
    pub(crate) fn new(
        generate_service: Option<GenerateService>,
        delegate: Option<service::message::Delegate>,
    ) -> Self {
        Self { generate_service, delegate }
    }

    async fn make_publisher(&self) -> Option<Publisher> {
        let maybe: OptionFuture<_> = self
            .delegate
            .as_ref()
            .map(|delegate| Publisher::create(delegate, MessengerType::Unbound))
            .into();
        maybe.await
    }

    /// Connect to a service with the given ProtocolMarker.
    ///
    /// If a GenerateService was specified at creation, the name of the service marker will be used
    /// to generate a service.
    pub(crate) async fn connect<P: DiscoverableProtocolMarker>(
        &self,
    ) -> Result<ExternalServiceProxy<P::Proxy>, Error> {
        let proxy = if let Some(generate_service) = &self.generate_service {
            let (client, server) = zx::Channel::create();
            ((generate_service)(P::PROTOCOL_NAME, server)).await?;
            P::Proxy::from_channel(fasync::Channel::from_channel(client))
        } else {
            connect_to_protocol::<P>()?
        };

        let publisher = self.make_publisher().await;
        let external_proxy = ExternalServiceProxy::new(proxy, publisher.clone());
        if let Some(p) = publisher {
            let timestamp = clock::inspect_format_now();
            p.send_event(Event::ExternalServiceEvent(ExternalServiceEvent::Created(
                P::PROTOCOL_NAME,
                timestamp.into(),
            )));
        }

        Ok(external_proxy)
    }

    pub(crate) async fn connect_with_publisher<P: DiscoverableProtocolMarker>(
        &self,
        publisher: Publisher,
    ) -> Result<ExternalServiceProxy<P::Proxy>, Error> {
        let proxy = if let Some(generate_service) = &self.generate_service {
            let (client, server) = zx::Channel::create();
            ((generate_service)(P::PROTOCOL_NAME, server)).await?;
            P::Proxy::from_channel(fasync::Channel::from_channel(client))
        } else {
            connect_to_protocol::<P>()?
        };

        let external_proxy = ExternalServiceProxy::new(proxy, Some(publisher.clone()));
        publisher.send_event(Event::ExternalServiceEvent(ExternalServiceEvent::Created(
            P::PROTOCOL_NAME,
            clock::inspect_format_now().into(),
        )));

        Ok(external_proxy)
    }

    /// Connect to a service by discovering a hardware device at the given glob-style pattern.
    ///
    /// The first discovered path will be used to connected.
    ///
    /// If a GenerateService was specified at creation, the name of the service marker will be used
    /// to generate a service and the path will be ignored.
    pub(crate) async fn connect_device_path<P: DiscoverableProtocolMarker>(
        &self,
        glob_pattern: &str,
    ) -> Result<ExternalServiceProxy<P::Proxy>, Error> {
        if self.generate_service.is_some() {
            // If a generate_service is already specified, just connect through there
            return self.connect::<P>().await;
        }

        let found_path = glob(glob_pattern)?
            .filter_map(|entry| entry.ok())
            .next()
            .ok_or_else(|| format_err!("failed to enumerate devices"))?;

        let path_str =
            found_path.to_str().ok_or_else(|| format_err!("failed to convert path to str"))?;

        let publisher = self.make_publisher().await;
        let external_proxy = ExternalServiceProxy::new(
            connect_to_protocol_at_path::<P>(path_str)?,
            publisher.clone(),
        );
        if let Some(p) = publisher {
            p.send_event(Event::ExternalServiceEvent(ExternalServiceEvent::Created(
                P::DEBUG_NAME,
                clock::inspect_format_now().into(),
            )));
        }

        Ok(external_proxy)
    }
}

/// Definition of events related to external api calls outside of the setting service.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ExternalServiceEvent {
    /// Event sent when an external service proxy is created. Contains
    /// the protocol name and the timestamp at which the connection
    /// was created.
    Created(
        &'static str,      // Protocol
        Cow<'static, str>, // Timestamp
    ),

    /// Event sent when a call is made on an external service proxy.
    /// Contains the protocol name, the stringified request, and the
    /// request timestamp.
    ApiCall(
        &'static str,      // Protocol
        Cow<'static, str>, // Request
        Cow<'static, str>, // Request timestamp
    ),

    /// Event sent when a non-error response is received on an external
    /// service proxy. Contains the protocol name, the response, the
    /// associated stringified request, and the request/response timestamps.
    ApiResponse(
        &'static str,      // Protocol
        Cow<'static, str>, // Response
        Cow<'static, str>, // Request
        Cow<'static, str>, // Request Timestamp
        Cow<'static, str>, // Response timestamp
    ),

    /// Event sent when an error is received on an external service proxy.
    /// Contains the protocol name, the error message, the associated
    /// stringified request, and the request/response timestamps.
    ApiError(
        &'static str,      // Protocol
        Cow<'static, str>, // Error msg
        Cow<'static, str>, // Request
        Cow<'static, str>, // Request timestamp
        Cow<'static, str>, // Error timestamp
    ),

    /// Event sent when an external service proxy is closed. Contains the
    /// protocol name, the associated stringified request, and the
    /// request/response timestamps.
    Closed(
        &'static str,      // Protocol
        Cow<'static, str>, // Request
        Cow<'static, str>, // Request timestamp
        Cow<'static, str>, // Response timestamp
    ),
}

/// A wrapper around a proxy, used to track disconnections.
///
/// This wraps any type implementing `Proxy`. Whenever any call returns a
/// `ClientChannelClosed` error, this wrapper publishes a closed event for
/// the wrapped proxy.
#[derive(Clone, Debug)]
pub struct ExternalServiceProxy<P>
where
    P: Proxy,
{
    proxy: P,
    publisher: Option<Publisher>,
}

impl<P> ExternalServiceProxy<P>
where
    P: Proxy,
{
    pub(crate) fn new(proxy: P, publisher: Option<Publisher>) -> Self {
        Self { proxy, publisher }
    }

    /// Handle the `result` of the event sent via the call or call_async methods
    /// and send the corresponding information to be logged to inspect.
    fn inspect_result<T>(
        &self,
        result: &Result<T, fidl::Error>,
        arg_str: String,
        req_timestamp: String,
        resp_timestamp: String,
    ) where
        T: Debug,
    {
        if let Some(p) = self.publisher.as_ref() {
            if let Err(fidl::Error::ClientChannelClosed { .. }) = result {
                p.send_event(Event::ExternalServiceEvent(ExternalServiceEvent::Closed(
                    P::Protocol::DEBUG_NAME,
                    arg_str.into(),
                    req_timestamp.into(),
                    resp_timestamp.into(),
                )));
            } else if let Err(e) = result {
                p.send_event(Event::ExternalServiceEvent(ExternalServiceEvent::ApiError(
                    P::Protocol::DEBUG_NAME,
                    format!("{e:?}").into(),
                    arg_str.into(),
                    req_timestamp.into(),
                    resp_timestamp.into(),
                )));
            } else {
                let payload = result.as_ref().expect("Could not extract external api call result");
                p.send_event(Event::ExternalServiceEvent(ExternalServiceEvent::ApiResponse(
                    P::Protocol::DEBUG_NAME,
                    format!("{payload:?}").into(),
                    arg_str.into(),
                    req_timestamp.into(),
                    resp_timestamp.into(),
                )));
            }
        }
    }

    /// Make a call to a synchronous API of the wrapped proxy. This should not be called directly,
    /// only from the call macro.
    pub(crate) fn call<T, F>(&self, func: F, arg_str: String) -> Result<T, fidl::Error>
    where
        F: FnOnce(&P) -> Result<T, fidl::Error>,
        T: std::fmt::Debug,
    {
        let req_timestamp = clock::inspect_format_now();
        if let Some(p) = self.publisher.as_ref() {
            p.send_event(Event::ExternalServiceEvent(ExternalServiceEvent::ApiCall(
                P::Protocol::DEBUG_NAME,
                arg_str.clone().into(),
                req_timestamp.clone().into(),
            )));
        }
        let result = func(&self.proxy);
        self.inspect_result(&result, arg_str, req_timestamp, clock::inspect_format_now());
        result
    }

    /// Make a call to an asynchronous API of the wrapped proxy. This should not be called directly,
    /// only from the call_async macro.
    pub(crate) async fn call_async<T, F, Fut>(
        &self,
        func: F,
        arg_str: String,
    ) -> Result<T, fidl::Error>
    where
        F: FnOnce(&P) -> Fut,
        Fut: Future<Output = Result<T, fidl::Error>>,
        T: std::fmt::Debug,
    {
        let req_timestamp = clock::inspect_format_now();
        if let Some(p) = self.publisher.as_ref() {
            p.send_event(Event::ExternalServiceEvent(ExternalServiceEvent::ApiCall(
                P::Protocol::DEBUG_NAME,
                arg_str.clone().into(),
                req_timestamp.clone().into(),
            )));
        }
        let result = func(&self.proxy).await;
        self.inspect_result(&result, arg_str, req_timestamp, clock::inspect_format_now());
        result
    }
}

/// Helper macro to simplify calls to proxy objects.
#[macro_export]
macro_rules! call {
    ($proxy:expr => $($call:tt)+) => {
        {
            let arg_string = $crate::format_call!($($call)+);
            $proxy.call(|p| p.$($call)+, arg_string)
        }
    };
}

/// Helper macro to simplify async calls to proxy objects.
#[macro_export]
macro_rules! call_async {
    ($proxy:expr => $($call:tt)+) => {
        {
            let arg_string = $crate::format_call!($($call)+);
            $proxy.call_async(|p| p.$($call)+, arg_string)
        }
    };
}

/// Helper macro to parse and stringify the arguments to `call` and `call_async`.
#[macro_export]
macro_rules! format_call {
    ($fn_name:ident($($arg:expr),*)) => {
        {
            let mut s = format!("{}(", stringify!($fn_name));
            $(
                s += &format!("{:?}", $arg);
            )*

            s += ")";
            s
        }
    };
}
