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

// Triggers a snapshot via FIDL

use log::{error, warn};

// Name of the crash-report product we're filing against.
const CRASH_PRODUCT_NAME: &'static str = "FuchsiaDetect";
// CRASH_PROGRAM_NAME serves two purposes:
// 1) It is sent with the crash report. It may show up on the server as
//   "process type".
// 2) The on-device crash reporting program associates this string with the
//   "product" CRASH_PRODUCT_NAME we're requesting to file against, so we
//   only have to send the program name and not the product name with each
//   crash report request.
//   This association is registered via a call to
//   CrashReportingProductRegister.upsert().
const CRASH_PROGRAM_NAME: &str = "triage_detect";

#[derive(Debug)]
pub struct SnapshotRequest {
    signature: String,
}

impl SnapshotRequest {
    pub fn new(signature: String) -> SnapshotRequest {
        SnapshotRequest { signature }
    }
}

// Code shamelessly stolen and slightly adapted from
// garnet/bin/power_manager/src/crash_report_handler.rs

use anyhow::{anyhow, format_err, Error};
//use async_trait::async_trait;
use fidl_fuchsia_feedback as fidl_feedback;
use fuchsia_async as fasync;
use futures::channel::mpsc;
use futures::stream::StreamExt;
use std::cell::RefCell;
use std::rc::Rc;

/// CrashReportHandler
///
/// Summary: Provides a mechanism for filing crash reports.
///
/// FIDL dependencies:
///     - fuchsia.feedback.CrashReporter: CrashReportHandler uses this protocol to communicate
///       with the CrashReporter service in order to file crash reports.
///     - fuchsia.feedback.CrashReportingProductRegister: CrashReportHandler uses this protocol
///       to communicate with the CrashReportingProductRegister service in order to configure
///       the crash reporting product it will be filing on.
///

/// Path to the CrashReporter service.
const CRASH_REPORTER_SVC: &'static str = "/svc/fuchsia.feedback.CrashReporter";
/// Path to the CrashReportingProductRegister service.
const CRASH_REGISTER_SVC: &'static str = "/svc/fuchsia.feedback.CrashReportingProductRegister";

/// The maximum number of pending crash report requests. This is needed because the FIDL API to file
/// a crash report does not return until the crash report has been fully generated, which can take
/// many seconds. Supporting pending crash reports means Detect can file
/// a new crash report for any other reason within that window, but the CrashReportHandler will
/// handle rate limiting to the CrashReporter service.
const MAX_PENDING_CRASH_REPORTS: usize = 10;

/// A builder for constructing the CrashReportHandler node.
pub struct CrashReportHandlerBuilder {
    proxy: Option<fidl_feedback::CrashReporterProxy>,
    max_pending_crash_reports: usize,
}

// This function is from fuchsia-mirror/garnet/bin/power_manager/src/utils.rs
/// Create and connect a FIDL proxy to the service at `path`
fn connect_proxy<T: fidl::endpoints::ServiceMarker>(
    path: &String,
) -> Result<T::Proxy, anyhow::Error> {
    let (proxy, server) = fidl::endpoints::create_proxy::<T>()
        .map_err(|e| anyhow::format_err!("Failed to create proxy: {}", e))?;

    fdio::service_connect(path, server.into_channel())
        .map_err(|s| anyhow::format_err!("Failed to connect to service at {}: {}", path, s))?;
    Ok(proxy)
}

/// Logs an error message if the passed in `result` is an error.
#[macro_export]
macro_rules! log_if_err {
    ($result:expr, $log_prefix:expr) => {
        if let Err(e) = $result.as_ref() {
            log::error!("{}: {}", $log_prefix, e);
        }
    };
}

impl CrashReportHandlerBuilder {
    pub fn new() -> Self {
        Self { proxy: None, max_pending_crash_reports: MAX_PENDING_CRASH_REPORTS }
    }

    #[cfg(test)]
    pub fn with_proxy(mut self, proxy: fidl_feedback::CrashReporterProxy) -> Self {
        self.proxy = Some(proxy);
        self
    }

    #[cfg(test)]
    pub fn with_max_pending_crash_reports(mut self, max: usize) -> Self {
        self.max_pending_crash_reports = max;
        self
    }

    pub fn build(self) -> Result<Rc<CrashReportHandler>, Error> {
        // Proxy is only pre-set for tests. If a proxy was not specified,
        // this is a good time to configure for our crash reporting product.
        if matches!(self.proxy, None) {
            let config_proxy = connect_proxy::<fidl_feedback::CrashReportingProductRegisterMarker>(
                &CRASH_REGISTER_SVC.to_string(),
            )?;
            let product_config = fidl_feedback::CrashReportingProduct {
                name: Some(CRASH_PRODUCT_NAME.to_string()),
                ..fidl_feedback::CrashReportingProduct::EMPTY
            };
            config_proxy.upsert(&CRASH_PROGRAM_NAME.to_string(), product_config)?;
        }
        // Connect to the CrashReporter service if a proxy wasn't specified
        let proxy = if self.proxy.is_some() {
            self.proxy.unwrap()
        } else {
            connect_proxy::<fidl_feedback::CrashReporterMarker>(&CRASH_REPORTER_SVC.to_string())?
        };

        // Set up the crash report sender that runs asynchronously
        let (channel, receiver) = mpsc::channel(self.max_pending_crash_reports);
        CrashReportHandler::begin_crash_report_sender(proxy, receiver);

        Ok(Rc::new(CrashReportHandler {
            channel_size: self.max_pending_crash_reports,
            crash_report_sender: RefCell::new(channel),
        }))
    }
}

pub struct CrashReportHandler {
    /// The channel to send new crash report requests to the asynchronous crash report sender
    /// future. The maximum pending crash reports are implicitly enforced by the channel length.
    crash_report_sender: RefCell<mpsc::Sender<SnapshotRequest>>,
    channel_size: usize,
}

impl CrashReportHandler {
    /// Handle a FileCrashReport message by sending the specified crash report signature over the
    /// channel to the crash report sender.
    pub fn request_snapshot(&self, request: SnapshotRequest) -> Result<(), Error> {
        // Try to send the crash report signature over the channel. If the channel is full, return
        // an error
        match self.crash_report_sender.borrow_mut().try_send(request) {
            Ok(()) => Ok(()),
            Err(e) if e.is_full() => {
                warn!("Too many crash reports pending: {}", e);
                Err(anyhow!("Pending crash reports exceeds max ({})", self.channel_size))
            }
            Err(e) => {
                warn!("Error sending crash report: {}", e);
                Err(anyhow!("{}", e))
            }
        }
    }

    /// Spawn and detach a future that receives crash report signatures over the channel and uses
    /// the proxy to send a File FIDL request to the CrashReporter service with the specified
    /// signatures.
    fn begin_crash_report_sender(
        proxy: fidl_feedback::CrashReporterProxy,
        mut receive_channel: mpsc::Receiver<SnapshotRequest>,
    ) {
        fasync::Task::local(async move {
            while let Some(request) = receive_channel.next().await {
                log_if_err!(
                    Self::send_crash_report(&proxy, request).await,
                    "Failed to file crash report"
                );
            }
            error!("Crash reporter task ended. Crash reports will no longer be filed. This should not happen.")
        })
        .detach();
    }

    /// Send a File request to the CrashReporter service with the specified crash report signature.
    async fn send_crash_report(
        proxy: &fidl_feedback::CrashReporterProxy,
        payload: SnapshotRequest,
    ) -> Result<(), Error> {
        warn!("Filing crash report, signature '{}'", payload.signature);
        let report = fidl_feedback::CrashReport {
            program_name: Some(CRASH_PROGRAM_NAME.to_string()),
            crash_signature: Some(payload.signature),
            ..fidl_feedback::CrashReport::EMPTY
        };

        let result = proxy.file(report).await.map_err(|e| format_err!("IPC error: {}", e))?;
        result.map_err(|e| format_err!("Service error: {}", e))
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use futures::TryStreamExt;
    use matches::assert_matches;

    /// Tests that the node responds to the FileCrashReport message and that the expected crash
    /// report is received by the CrashReporter service.
    #[fasync::run_singlethreaded(test)]
    async fn test_crash_report_content() {
        // The crash report signature to use and verify against
        let crash_report_signature = "TestCrashReportSignature";

        // Set up the CrashReportHandler node
        let (proxy, mut stream) =
            fidl::endpoints::create_proxy_and_stream::<fidl_feedback::CrashReporterMarker>()
                .unwrap();
        let crash_report_handler =
            CrashReportHandlerBuilder::new().with_proxy(proxy).build().unwrap();

        // File a crash report
        crash_report_handler
            .request_snapshot(SnapshotRequest::new(crash_report_signature.to_string()))
            .unwrap();

        // Verify the fake service receives the crash report with expected data
        if let Ok(Some(fidl_feedback::CrashReporterRequest::File { responder: _, report })) =
            stream.try_next().await
        {
            assert_eq!(
                report,
                fidl_feedback::CrashReport {
                    program_name: Some(CRASH_PROGRAM_NAME.to_string()),
                    crash_signature: Some(crash_report_signature.to_string()),
                    ..fidl_feedback::CrashReport::EMPTY
                }
            );
        } else {
            panic!("Did not receive a crash report");
        }
    }

    /// Tests that the number of pending crash reports is correctly bounded.
    #[test]
    fn test_crash_report_pending_reports() {
        let mut exec = fasync::Executor::new().unwrap();

        // Set up the proxy/stream and node outside of the large future used below. This way we can
        // still poll the stream after the future completes.
        let (proxy, mut stream) =
            fidl::endpoints::create_proxy_and_stream::<fidl_feedback::CrashReporterMarker>()
                .unwrap();
        let crash_report_handler = CrashReportHandlerBuilder::new()
            .with_proxy(proxy)
            .with_max_pending_crash_reports(1)
            .build()
            .unwrap();

        // Run most of the test logic inside a top level future for better ergonomics
        exec.run_singlethreaded(async {
            // Set up the CrashReportHandler node. The request stream is never serviced, so when the
            // node makes the FIDL call to file the crash report, the call will block indefinitely.
            // This lets us test the pending crash report counts.

            // The first FileCrashReport should succeed
            assert_matches!(
                crash_report_handler
                    .request_snapshot(SnapshotRequest::new("TestCrash1".to_string())),
                Ok(())
            );

            // The second FileCrashReport should also succeed because since the first is now in
            // progress, this is now the first "pending" report request
            assert_matches!(
                crash_report_handler
                    .request_snapshot(SnapshotRequest::new("TestCrash2".to_string())),
                Ok(())
            );

            // Since the first request has not completed, and there is already one pending request,
            // this request should fail
            assert_matches!(
                crash_report_handler
                    .request_snapshot(SnapshotRequest::new("TestCrash3".to_string())),
                Err(_)
            );

            // Verify the signature of the first crash report
            if let Ok(Some(fidl_feedback::CrashReporterRequest::File { responder, report })) =
                stream.try_next().await
            {
                // Send a reply to allow the node to process the next crash report
                let _ = responder.send(&mut Ok(()));
                assert_eq!(
                    report,
                    fidl_feedback::CrashReport {
                        program_name: Some(CRASH_PROGRAM_NAME.to_string()),
                        crash_signature: Some("TestCrash1".to_string()),
                        ..fidl_feedback::CrashReport::EMPTY
                    }
                );
            } else {
                panic!("Did not receive a crash report");
            }

            // Verify the signature of the second crash report
            if let Ok(Some(fidl_feedback::CrashReporterRequest::File { responder, report })) =
                stream.try_next().await
            {
                // Send a reply to allow the node to process the next crash report
                let _ = responder.send(&mut Ok(()));
                assert_eq!(
                    report,
                    fidl_feedback::CrashReport {
                        program_name: Some(CRASH_PROGRAM_NAME.to_string()),
                        crash_signature: Some("TestCrash2".to_string()),
                        ..fidl_feedback::CrashReport::EMPTY
                    }
                );
            } else {
                panic!("Did not receive a crash report");
            }
        });

        // Verify there are no more crash reports. Use `run_until_stalled` because `next` is
        // expected to block until a new crash report is ready, which shouldn't happen here.
        assert!(exec.run_until_stalled(&mut stream.next()).is_pending());
    }
}
