// 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},
    fidl::endpoints::{ProtocolMarker, ServerEnd},
    fidl_fuchsia_component as fcomponent, fidl_fuchsia_io as fio,
    fuchsia_component::client::connect_to_protocol_at_path,
    fuchsia_zircon as zx,
    lazy_static::lazy_static,
    std::collections::VecDeque,
    thiserror::Error,
};

lazy_static! {
    /// The path of the static event stream that, by convention, synchronously listens for
    /// Resolved events.
    pub static ref START_COMPONENT_TREE_STREAM: String = "StartComponentTree".into();
}

/// Returns the string name for the given `event_type`
pub fn event_name(event_type: &fcomponent::EventType) -> String {
    match event_type {
        fcomponent::EventType::CapabilityRequested => "capability_requested",
        fcomponent::EventType::Discovered => "discovered",
        fcomponent::EventType::Destroyed => "destroyed",
        fcomponent::EventType::Resolved => "resolved",
        fcomponent::EventType::Unresolved => "unresolved",
        fcomponent::EventType::Started => "started",
        fcomponent::EventType::Stopped => "stopped",
        fcomponent::EventType::DebugStarted => "debug_started",
    }
    .to_string()
}

enum InternalStream {
    New(fcomponent::EventStreamProxy),
}

pub struct EventStream {
    stream: InternalStream,
    buffer: VecDeque<fcomponent::Event>,
}

#[derive(Debug, Error, Clone)]
pub enum EventStreamError {
    #[error("Stream terminated unexpectedly")]
    StreamClosed,
}

impl EventStream {
    pub fn new(stream: fcomponent::EventStreamProxy) -> Self {
        Self { stream: InternalStream::New(stream), buffer: VecDeque::new() }
    }

    pub fn open_at_path_pipelined(path: impl Into<String>) -> Result<Self, Error> {
        Ok(Self::new(connect_to_protocol_at_path::<fcomponent::EventStreamMarker>(&path.into())?))
    }

    pub async fn open_at_path(path: impl Into<String>) -> Result<Self, Error> {
        let event_stream =
            connect_to_protocol_at_path::<fcomponent::EventStreamMarker>(&path.into())?;
        event_stream.wait_for_ready().await?;
        Ok(Self::new(event_stream))
    }

    pub async fn open() -> Result<Self, Error> {
        let event_stream = connect_to_protocol_at_path::<fcomponent::EventStreamMarker>(
            "/svc/fuchsia.component.EventStream",
        )?;
        event_stream.wait_for_ready().await?;
        Ok(Self::new(event_stream))
    }

    pub fn open_pipelined() -> Result<Self, Error> {
        Ok(Self::new(connect_to_protocol_at_path::<fcomponent::EventStreamMarker>(
            "/svc/fuchsia.component.EventStream",
        )?))
    }

    pub async fn next(&mut self) -> Result<fcomponent::Event, EventStreamError> {
        if let Some(event) = self.buffer.pop_front() {
            return Ok(event);
        }
        match &mut self.stream {
            InternalStream::New(stream) => {
                match stream.get_next().await {
                    Ok(events) => {
                        let mut iter = events.into_iter();
                        if let Some(real_event) = iter.next() {
                            let ret = real_event;
                            while let Some(value) = iter.next() {
                                self.buffer.push_back(value);
                            }
                            return Ok(ret);
                        } else {
                            // This should never happen, we should always
                            // have at least one event.
                            Err(EventStreamError::StreamClosed)
                        }
                    }
                    Err(_) => Err(EventStreamError::StreamClosed),
                }
            }
        }
    }
}

/// Common features of any event - event type, target moniker, conversion function
pub trait Event: TryFrom<fcomponent::Event, Error = anyhow::Error> {
    const TYPE: fcomponent::EventType;
    const NAME: &'static str;

    fn target_moniker(&self) -> &str;
    fn component_url(&self) -> &str;
    fn timestamp(&self) -> zx::Time;
    fn is_ok(&self) -> bool;
    fn is_err(&self) -> bool;
}

#[derive(Copy, Debug, PartialEq, Eq, Clone, Ord, PartialOrd)]
/// Simplifies the exit status represented by an Event. All stop status values
/// that indicate failure are crushed into `Crash`.
pub enum ExitStatus {
    Clean,
    Crash(i32),
}

impl From<i32> for ExitStatus {
    fn from(exit_status: i32) -> Self {
        match exit_status {
            0 => ExitStatus::Clean,
            _ => ExitStatus::Crash(exit_status),
        }
    }
}

#[derive(Debug)]
struct EventHeader {
    event_type: fcomponent::EventType,
    component_url: String,
    moniker: String,
    timestamp: zx::Time,
}

impl TryFrom<fcomponent::EventHeader> for EventHeader {
    type Error = anyhow::Error;

    fn try_from(header: fcomponent::EventHeader) -> Result<Self, Self::Error> {
        let event_type = header.event_type.ok_or(format_err!("No event type"))?;
        let component_url = header.component_url.ok_or(format_err!("No component url"))?;
        let moniker = header.moniker.ok_or(format_err!("No moniker"))?;
        let timestamp = zx::Time::from_nanos(
            header.timestamp.ok_or(format_err!("Missing timestamp from the Event object"))?,
        );
        Ok(EventHeader { event_type, component_url, moniker, timestamp })
    }
}

#[derive(Debug, PartialEq, Eq)]
pub struct EventError {
    pub description: String,
}

/// The macro defined below will automatically create event classes corresponding
/// to their events.fidl and hooks.rs counterparts. Every event class implements
/// the Event and Handler traits. These minimum requirements allow every event to
/// be handled by the events client library.

/// Creates an event class based on event type and an optional payload
/// * event_type -> FIDL name for event type
/// * payload -> If an event has a payload, describe the additional params:
///   * name -> FIDL name for the payload
///   * data -> If a payload contains data items, describe the additional params:
///     * name -> FIDL name for the data item
///     * ty -> Rust type for the data item
///   * client_protocols -> If a payload contains client-side protocols, describe
///     the additional params:
///     * name -> FIDL name for the protocol
///     * ty -> Rust type for the protocol proxy
///   * server_protocols -> If a payload contains server-side protocols, describe
///     the additional params:
///     * name -> FIDL name for the protocol
// TODO(https://fxbug.dev/42131403): This marco is getting complicated. Consider replacing it
//                  with a procedural macro.
macro_rules! create_event {
    // Entry points
    (
        event_type: $event_type:ident,
        event_name: $event_name:ident,
        payload: {
            data: {$(
                {
                    name: $data_name:ident,
                    ty: $data_ty:ty,
                }
            )*},
            client_protocols: {$(
                {
                    name: $client_protocol_name:ident,
                    ty: $client_protocol_ty:ty,
                }
            )*},
            server_protocols: {$(
                {
                    name: $server_protocol_name:ident,
                }
            )*},
        },
        error_payload: {
            $(
                {
                    name: $error_data_name:ident,
                    ty: $error_data_ty:ty,
                }
            )*
        }
    ) => {
        paste::paste! {
            #[derive(Debug)]
            pub struct [<$event_type Payload>] {
                $(pub $client_protocol_name: $client_protocol_ty,)*
                $(pub $server_protocol_name: Option<zx::Channel>,)*
                $(pub $data_name: $data_ty,)*
            }

            #[derive(Debug)]
            pub struct [<$event_type Error>] {
                $(pub $error_data_name: $error_data_ty,)*
                pub description: String,
            }

            #[derive(Debug)]
            pub struct $event_type {
                header: EventHeader,
                result: Result<[<$event_type Payload>], [<$event_type Error>]>,
            }

            impl $event_type {
                pub fn result<'a>(&'a self) -> Result<&'a [<$event_type Payload>], &'a [<$event_type Error>]> {
                    self.result.as_ref()
                }

                $(
                    pub fn [<take_ $server_protocol_name>]<T: ProtocolMarker>(&mut self)
                            -> Option<T::RequestStream> {
                        self.result.as_mut()
                            .ok()
                            .and_then(|payload| payload.$server_protocol_name.take())
                            .and_then(|channel| {
                                let server_end = ServerEnd::<T>::new(channel);
                                server_end.into_stream().ok()
                            })
                    }
                )*
            }

            impl Event for $event_type {
                const TYPE: fcomponent::EventType = fcomponent::EventType::$event_type;
                const NAME: &'static str = stringify!($event_name);

                fn target_moniker(&self) -> &str {
                    &self.header.moniker
                }

                fn component_url(&self) -> &str {
                    &self.header.component_url
                }

                fn timestamp(&self) -> zx::Time {
                    self.header.timestamp
                }

                fn is_ok(&self) -> bool {
                    self.result.is_ok()
                }

                fn is_err(&self) -> bool {
                    self.result.is_err()
                }
            }

            impl TryFrom<fcomponent::Event> for $event_type {
                type Error = anyhow::Error;

                fn try_from(event: fcomponent::Event) -> Result<Self, Self::Error> {
                    // Extract the payload from the Event object.
                    let result = match event.payload {
                        Some(payload) => {
                            // This payload will be unused for event types that have no additional
                            // fields.
                            #[allow(unused)]
                            let payload = match payload {
                                fcomponent::EventPayload::$event_type(payload) => Ok(payload),
                                _ => Err(format_err!("Incorrect payload type, {:?}", payload)),
                            }?;

                            // Extract the additional data from the Payload object.
                            $(
                                let $data_name: $data_ty = payload.$data_name.ok_or(
                                    format_err!("Missing $data_name from $event_type object")
                                )?.into();
                            )*

                            // Extract the additional protocols from the Payload object.
                            $(
                                let $client_protocol_name: $client_protocol_ty = payload.$client_protocol_name.ok_or(
                                    format_err!("Missing $client_protocol_name from $event_type object")
                                )?.into_proxy()?;
                            )*
                            $(
                                let $server_protocol_name: Option<zx::Channel> =
                                    Some(payload.$server_protocol_name.ok_or(
                                        format_err!("Missing $server_protocol_name from $event_type object")
                                    )?);
                            )*

                            #[allow(dead_code)]
                            let payload = paste::paste! {
                                [<$event_type Payload>] {
                                    $($data_name,)*
                                    $($client_protocol_name,)*
                                    $($server_protocol_name,)*
                                }
                            };

                            Ok(Ok(payload))
                        },
                        None => Err(format_err!("Missing event_result from Event object")),
                    }?;

                    let event = {
                        let header = event.header
                            .ok_or(format_err!("Missing Event header"))
                            .and_then(|header| EventHeader::try_from(header))?;

                        if header.event_type != Self::TYPE {
                            return Err(format_err!("Incorrect event type"));
                        }

                        $event_type { header, result }
                    };
                    Ok(event)
                }
            }
        }
    };
    ($event_type:ident, $event_name:ident) => {
        create_event!(event_type: $event_type, event_name: $event_name,
                      payload: {
                          data: {},
                          client_protocols: {},
                          server_protocols: {},
                      },
                      error_payload: {});
    };
}

// To create a class for an event, use the above macro here.
create_event!(Discovered, discovered);
create_event!(Destroyed, destroyed);
create_event!(Resolved, resolved);
create_event!(Unresolved, unresolved);
create_event!(Started, started);
create_event!(
    event_type: Stopped,
    event_name: stopped,
    payload: {
        data: {
            {
                name: status,
                ty: ExitStatus,
            }
        },
        client_protocols: {},
        server_protocols: {},
    },
    error_payload: {}
);
create_event!(
    event_type: CapabilityRequested,
    event_name: capability_requested,
    payload: {
        data: {
            {
                name: name,
                ty: String,
            }
        },
        client_protocols: {},
        server_protocols: {
            {
                name: capability,
            }
        },
    },
    error_payload: {
        {
            name: name,
            ty: String,
        }
    }
);
create_event!(
    event_type: DebugStarted,
    event_name: debug_started,
    payload: {
        data: {
            {
                name: break_on_start,
                ty: zx::EventPair,
            }
        },
        client_protocols: {
            {
                name: runtime_dir,
                ty: fio::DirectoryProxy,
            }
        },
        server_protocols: {},
    },
    error_payload: {}
);
