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

//! Defines `CobaltSender` to encapsulate encoding `CobaltEvent` and sending them to the Cobalt
//! FIDL service.

use {
    cobalt_client::traits::AsEventCodes,
    fidl_fuchsia_cobalt::{CobaltEvent, CountEvent, EventPayload, HistogramBucket},
    futures::channel::mpsc,
    log::{error, info},
    std::sync::{
        atomic::{AtomicBool, Ordering},
        Arc,
    },
};

macro_rules! gen_comment {
    ($x:expr) => {
        #[doc = $x]
        extern {}
    };
    ($x:expr, $($tt:tt)*) => {
        #[doc = $x]
        $($tt)*
    };
}

/// Wraps around an `mpsc::Sender` to allow sending CobaltEvents asynchronously to the Cobalt
/// FIDL service.
#[derive(Clone, Debug)]
pub struct CobaltSender {
    sender: mpsc::Sender<CobaltEvent>,
    is_blocked: Arc<AtomicBool>,
}

macro_rules! impl_wrapped_methods {
    ($(#[$variant:ident] $name:ident($($arg:ident: $ty:ty),*))*) => {
        $(
            gen_comment!{
                concat! {
                    "Logs a CobaltEvent of type `EventPayload::",
                    stringify!($variant),
                    "` by wrapping a call to `CobaltSenderWithComponent::",
                    stringify!($name), "`."
                },
                pub fn $name<Codes: AsEventCodes>(
                    &mut self,
                    metric_id: u32,
                    event_codes: Codes,
                    $($arg: $ty),*
                ) {
                    self.with_component().$name::<_, String, _>(
                        metric_id,
                        event_codes,
                        None,
                        $($arg),*
                    );
                }
            }
        )*
    }
}

impl CobaltSender {
    /// Constructs a new CobaltSender object.
    ///
    /// # Arguments
    ///
    /// * `sender` - The sending end of a `mpsc::channel`
    pub fn new(sender: mpsc::Sender<CobaltEvent>) -> CobaltSender {
        CobaltSender { sender, is_blocked: Arc::new(AtomicBool::new(false)) }
    }

    /// Accesses the sidecar struct `CobaltSenderWithComponent` to allow logging to cobalt with
    /// component strings.
    pub fn with_component(&mut self) -> CobaltSenderWithComponent<'_> {
        CobaltSenderWithComponent(self)
    }

    /// Logs a CobaltEvent of type `EventPayload::Event`.
    pub fn log_event<Codes: AsEventCodes>(&mut self, metric_id: u32, event_codes: Codes) {
        self.log_event_value(CobaltEvent {
            metric_id,
            event_codes: event_codes.as_event_codes(),
            component: None,
            payload: EventPayload::Event(fidl_fuchsia_cobalt::Event {}),
        });
    }

    /// Logs a plain CobaltEvent.
    pub fn log_cobalt_event(&mut self, event: CobaltEvent) {
        self.log_event_value(event);
    }

    fn log_event_value(&mut self, event: CobaltEvent) {
        if self.sender.try_send(event).is_err() {
            #[allow(deprecated)] // TODO(fxbug.dev/67113) migrate to compare_exchange
            let was_blocked = self.is_blocked.compare_and_swap(false, true, Ordering::SeqCst);
            if !was_blocked {
                error!("cobalt sender drops a event/events: either buffer is full or no receiver is waiting");
            }
        } else {
            #[allow(deprecated)] // TODO(fxbug.dev/67113) migrate to compare_exchange
            let was_blocked = self.is_blocked.compare_and_swap(true, false, Ordering::SeqCst);
            if was_blocked {
                info!("cobalt sender recovers and resumes sending")
            }
        }
    }

    impl_wrapped_methods! {
        #[CountEvent]
        log_event_count(period_duration_micros: i64, count: i64)

        #[ElapsedMicros]
        log_elapsed_time(elapsed_micros: i64)

        #[Fps]
        log_frame_rate(fps: f32)

        #[MemoryBytesUsed]
        log_memory_usage(bytes: i64)

        #[IntHistogram]
        log_int_histogram(values: Vec<HistogramBucket>)
    }
}

/// Allows logging to cobalt with component strings
///
/// Component strings are relatively uncommon, so this is a sidecar struct that contains
/// methods with component string arguments. To access it, you call
/// `CobaltSender::with_component()` followed by the method. Only event types that accept
/// component strings are present on this struct.
pub struct CobaltSenderWithComponent<'a>(&'a mut CobaltSender);

macro_rules! impl_log_methods{
    ($(#[$variant:ident] $name:ident($($arg:ident: $ty:ty),*) => $payload:expr)*) => {
        $(
            gen_comment!{
                concat! {
                    "Logs a CobaltEvent of type `EventPayload::",
                    stringify!($variant),
                    "` with a component string"
                },
                pub fn $name<Codes, S, Component>(
                    &mut self,
                    metric_id: u32,
                    event_codes: Codes,
                    component: Component,
                    $($arg: $ty),*
                ) where
                    Codes: AsEventCodes,
                    S: Into<String>,
                    Component: Into<Option<S>>
                {
                    self.0.log_event_value(CobaltEvent {
                        metric_id,
                        component: component.into().map(|s| s.into()),
                        event_codes: event_codes.as_event_codes(),
                        payload: $payload
                    })
                }
            }
        )*
    }
}

impl<'a> CobaltSenderWithComponent<'a> {
    impl_log_methods! {
        #[CountEvent]
        log_event_count(period_duration_micros: i64, count: i64) => {
            EventPayload::EventCount(CountEvent {
                period_duration_micros,
                count,
            })
        }

        #[ElapsedMicros]
        log_elapsed_time(elapsed_micros: i64) => {
            EventPayload::ElapsedMicros(elapsed_micros)
        }

        #[Fps]
        log_frame_rate(fps: f32) => {
            EventPayload::Fps(fps)
        }

        #[MemoryBytesUsed]
        log_memory_usage(bytes: i64) => {
            EventPayload::MemoryBytesUsed(bytes)
        }

        #[IntHistogram]
        log_int_histogram(values: Vec<HistogramBucket>) => {
            EventPayload::IntHistogram(values)
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_cobalt_sender() {
        let (sender, mut receiver) = mpsc::channel(1);
        let mut sender = CobaltSender::new(sender);
        sender.log_event(1, 1);
        assert_eq!(
            receiver.try_next().unwrap().unwrap(),
            CobaltEvent {
                metric_id: 1,
                event_codes: vec![1],
                component: None,
                payload: EventPayload::Event(fidl_fuchsia_cobalt::Event {}),
            }
        );

        sender.log_event_count(2, (), 10, 1);
        assert_eq!(
            receiver.try_next().unwrap().unwrap(),
            CobaltEvent {
                metric_id: 2,
                event_codes: vec![],
                component: None,
                payload: EventPayload::EventCount(CountEvent {
                    period_duration_micros: 10,
                    count: 1
                })
            }
        );

        sender.with_component().log_event_count(2, (), "test", 11, 2);
        assert_eq!(
            receiver.try_next().unwrap().unwrap(),
            CobaltEvent {
                metric_id: 2,
                event_codes: vec![],
                component: Some("test".to_owned()),
                payload: EventPayload::EventCount(CountEvent {
                    period_duration_micros: 11,
                    count: 2
                })
            }
        );

        sender.log_elapsed_time(3, [1, 2], 30);
        assert_eq!(
            receiver.try_next().unwrap().unwrap(),
            CobaltEvent {
                metric_id: 3,
                event_codes: vec![1, 2],
                component: None,
                payload: EventPayload::ElapsedMicros(30),
            }
        );

        sender.with_component().log_elapsed_time(3, [1, 2], "test".to_owned(), 30);
        assert_eq!(
            receiver.try_next().unwrap().unwrap(),
            CobaltEvent {
                metric_id: 3,
                event_codes: vec![1, 2],
                component: Some("test".to_owned()),
                payload: EventPayload::ElapsedMicros(30),
            }
        );

        sender.log_frame_rate(4, [1, 2, 3, 4], 10.0);
        assert_eq!(
            receiver.try_next().unwrap().unwrap(),
            CobaltEvent {
                metric_id: 4,
                event_codes: vec![1, 2, 3, 4],
                component: None,
                payload: EventPayload::Fps(10.0),
            }
        );

        sender.with_component().log_frame_rate(4, (), "testing", 100.0);
        assert_eq!(
            receiver.try_next().unwrap().unwrap(),
            CobaltEvent {
                metric_id: 4,
                event_codes: vec![],
                component: Some("testing".to_owned()),
                payload: EventPayload::Fps(100.0),
            }
        );

        sender.log_memory_usage(5, [1, 2, 3, 4, 5], 100);
        assert_eq!(
            receiver.try_next().unwrap().unwrap(),
            CobaltEvent {
                metric_id: 5,
                event_codes: vec![1, 2, 3, 4, 5],
                component: None,
                payload: EventPayload::MemoryBytesUsed(100),
            }
        );

        sender.with_component().log_memory_usage(5, [1, 2, 3, 4, 5], "a test", 100);
        assert_eq!(
            receiver.try_next().unwrap().unwrap(),
            CobaltEvent {
                metric_id: 5,
                event_codes: vec![1, 2, 3, 4, 5],
                component: Some("a test".to_owned()),
                payload: EventPayload::MemoryBytesUsed(100),
            }
        );

        sender.log_int_histogram(4, [1, 2, 3], vec![HistogramBucket { index: 2, count: 2 }]);
        assert_eq!(
            receiver.try_next().unwrap().unwrap(),
            CobaltEvent {
                metric_id: 4,
                event_codes: vec![1, 2, 3],
                component: None,
                payload: EventPayload::IntHistogram(vec![HistogramBucket { index: 2, count: 2 }]),
            }
        );

        sender.with_component().log_int_histogram(
            4,
            [1, 2, 3],
            "Component",
            vec![HistogramBucket { index: 2, count: 2 }],
        );
        assert_eq!(
            receiver.try_next().unwrap().unwrap(),
            CobaltEvent {
                metric_id: 4,
                event_codes: vec![1, 2, 3],
                component: Some("Component".to_owned()),
                payload: EventPayload::IntHistogram(vec![HistogramBucket { index: 2, count: 2 }]),
            }
        );
    }
}
