// 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 crate::error::PowerManagerError;
use crate::log_if_err;
use crate::message::{Message, MessageReturn};
use crate::node::Node;
use crate::platform_metrics::PlatformMetric;
use crate::shutdown_request::{RebootReason, ShutdownRequest};
use crate::temperature_handler::TemperatureFilter;
use crate::types::{Celsius, Seconds};
use crate::utils::get_current_timestamp;
use anyhow::{format_err, Error};
use async_trait::async_trait;
use fuchsia_async as fasync;
use futures::{
    future::{FutureExt, LocalBoxFuture},
    stream::FuturesUnordered,
    StreamExt,
};
use log::*;
use serde_derive::Deserialize;
use serde_json as json;
use std::collections::HashMap;
use std::rc::Rc;

/// Node: ThermalShutdown
///
/// Summary: Monitors a single temperature sensor using a provided TemperatureHandler node. When the
/// observed temperature crosses the configured temperature threshold, the node will command a
/// system reboot.
///
/// Handles Messages: N/A
///
/// Sends Messages:
///     - ReadTemperature
///     - SystemShutdown
///
/// FIDL dependencies: N/A

pub struct ThermalShutdownBuilder {
    thermal_shutdown_temperature: Celsius,
    poll_interval: Seconds,
    filter_time_constant: Seconds,
    temperature_node: Rc<dyn Node>,
    system_shutdown_node: Rc<dyn Node>,
    platform_metrics_node: Rc<dyn Node>,
}

impl ThermalShutdownBuilder {
    #[cfg(test)]
    fn new(
        temperature_node: Rc<dyn Node>,
        system_shutdown_node: Rc<dyn Node>,
        platform_metrics_node: Rc<dyn Node>,
    ) -> Self {
        ThermalShutdownBuilder {
            thermal_shutdown_temperature: Celsius(0.0),
            poll_interval: Seconds(0.0),
            filter_time_constant: Seconds(10.0),
            temperature_node,
            system_shutdown_node,
            platform_metrics_node,
        }
    }

    pub fn new_from_json(json_data: json::Value, nodes: &HashMap<String, Rc<dyn Node>>) -> Self {
        #[derive(Deserialize)]
        struct Config {
            thermal_shutdown_temperature_c: f64,
            poll_interval_s: f64,
            filter_time_constant_s: f64,
        }

        #[derive(Deserialize)]
        struct Dependencies {
            temperature_handler_node: String,
            system_shutdown_node: String,
            platform_metrics_node: String,
        }

        #[derive(Deserialize)]
        struct JsonData {
            config: Config,
            dependencies: Dependencies,
        }

        let data: JsonData = json::from_value(json_data).unwrap();
        Self {
            thermal_shutdown_temperature: Celsius(data.config.thermal_shutdown_temperature_c),
            poll_interval: Seconds(data.config.poll_interval_s),
            filter_time_constant: Seconds(data.config.filter_time_constant_s),
            temperature_node: nodes[&data.dependencies.temperature_handler_node].clone(),
            system_shutdown_node: nodes[&data.dependencies.system_shutdown_node].clone(),
            platform_metrics_node: nodes[&data.dependencies.platform_metrics_node].clone(),
        }
    }

    #[cfg(test)]
    pub fn with_thermal_shutdown_temperature(mut self, temperature: Celsius) -> Self {
        self.thermal_shutdown_temperature = temperature;
        self
    }

    pub fn build<'a>(
        self,
        futures_out: &FuturesUnordered<LocalBoxFuture<'a, ()>>,
    ) -> Result<Rc<ThermalShutdown>, Error> {
        let node = Rc::new(ThermalShutdown {
            temperature_filter: TemperatureFilter::new(
                self.temperature_node.clone(),
                self.filter_time_constant,
            ),
            thermal_shutdown_temperature: self.thermal_shutdown_temperature,
            poll_interval: self.poll_interval,
            temperature_node: self.temperature_node,
            system_shutdown_node: self.system_shutdown_node,
            platform_metrics_node: self.platform_metrics_node,
        });

        futures_out.push(node.clone().polling_loop());
        Ok(node)
    }
}

pub struct ThermalShutdown {
    /// Provides filtered temperature values according to the configured filter constant.
    temperature_filter: TemperatureFilter,

    /// Temperature threshold in Celsius at which the node will command a system reboot.
    thermal_shutdown_temperature: Celsius,

    /// Time interval in seconds that the node will read a new temperature value.
    poll_interval: Seconds,

    /// Node to provide the temperature readings via the ReadTemperature message.
    temperature_node: Rc<dyn Node>,

    /// Node to provide the system reboot functionality via the SystemShutdown message.
    system_shutdown_node: Rc<dyn Node>,

    /// The node that we'll notify when throttling conditions have changed, for logging and metrics
    /// purposes.
    platform_metrics_node: Rc<dyn Node>,
}

impl ThermalShutdown {
    /// Creates a Future that periodically polls the temperature and checks it against the
    /// configured threshold.
    fn polling_loop<'a>(self: Rc<Self>) -> LocalBoxFuture<'a, ()> {
        let mut periodic_timer = fasync::Interval::new(self.poll_interval.into());

        async move {
            while let Some(()) = periodic_timer.next().await {
                let result = self.poll_temperature().await;
                log_if_err!(result, "Error while polling temperature");
            }
        }
        .boxed_local()
    }

    /// Polls the temperature sensor once and checks the reading against the configured threshold.
    async fn poll_temperature(&self) -> Result<(), Error> {
        fuchsia_trace::duration!("power_manager", "ThermalShutdown::poll_temperature");
        let timestamp = get_current_timestamp();

        if self.temperature_filter.get_temperature(timestamp).await?.filtered
            >= self.thermal_shutdown_temperature
        {
            info!("{:?} crossed high temperature mark. Rebooting...", self.temperature_node.name());
            let msg = Message::LogPlatformMetric(PlatformMetric::ThrottlingResultShutdown);
            log_if_err!(
                self.send_message(&self.platform_metrics_node, &msg).await,
                format!("Failed to log platform metric {:?}", msg)
            );
            self.send_message(
                &self.system_shutdown_node,
                &Message::SystemShutdown(ShutdownRequest::Reboot(RebootReason::HighTemperature)),
            )
            .await
            .map_err(|e| format_err!("Failed to shut down the system: {}", e))?;
        }

        Ok(())
    }
}

#[async_trait(?Send)]
impl Node for ThermalShutdown {
    fn name(&self) -> String {
        "ThermalShutdown".to_string()
    }

    async fn handle_message(&self, msg: &Message) -> Result<MessageReturn, PowerManagerError> {
        match msg {
            _ => Err(PowerManagerError::Unsupported),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::test::mock_node::{create_dummy_node, MessageMatcher, MockNodeMaker};
    use crate::{msg_eq, msg_ok_return};

    /// Tests that well-formed configuration JSON does not panic the `new_from_json` function.
    #[fasync::run_singlethreaded(test)]
    async fn test_new_from_json() {
        let json_data = json::json!({
            "type": "ThermalShutdown",
            "name": "thermal_shutdown",
            "config": {
                "thermal_shutdown_temperature_c": 1.2,
                "poll_interval_s": 3.4,
                "filter_time_constant_s": 5.6
            },
            "dependencies": {
                "system_shutdown_node": "shutdown",
                "temperature_handler_node": "temperature",
                "platform_metrics_node": "metrics"
              },
        });

        let mut nodes: HashMap<String, Rc<dyn Node>> = HashMap::new();
        nodes.insert("temperature".to_string(), create_dummy_node());
        nodes.insert("shutdown".to_string(), create_dummy_node());
        nodes.insert("metrics".to_string(), create_dummy_node());
        let _ = ThermalShutdownBuilder::new_from_json(json_data, &nodes);
    }

    /// Tests that when the node reads a temperature that exceeds the configured threshold value, it
    /// triggers a system shutdown.
    #[fasync::run_singlethreaded(test)]
    async fn test_triggered_shutdown() {
        let mut mock_maker = MockNodeMaker::new();
        let temperature_node = mock_maker.make(
            "Temperature",
            vec![(msg_eq!(ReadTemperature), msg_ok_return!(ReadTemperature(Celsius(100.0))))],
        );
        let shutdown_node = mock_maker.make(
            "Shutdown",
            vec![(
                msg_eq!(SystemShutdown(ShutdownRequest::Reboot(RebootReason::HighTemperature))),
                msg_ok_return!(SystemShutdown),
            )],
        );

        let node_futures = FuturesUnordered::new();
        let node =
            ThermalShutdownBuilder::new(temperature_node, shutdown_node, create_dummy_node())
                .with_thermal_shutdown_temperature(Celsius(99.0))
                .build(&node_futures)
                .unwrap();
        assert!(node.poll_temperature().await.is_ok());
    }

    /// Tests that when the node commands a system shutdown due to high temperature, it also calls
    /// into the Platform metrics instance to log the thermal shutdown.
    #[test]
    fn test_platform_metrics() {
        let mut mock_maker = MockNodeMaker::new();
        let mut executor = fasync::TestExecutor::new_with_fake_time().unwrap();
        executor.set_fake_time(Seconds(10.0).into()); // arbitrary nonzero time
        let node_futures = FuturesUnordered::new();
        let node = ThermalShutdownBuilder::new(
            mock_maker.make(
                "Temperature",
                vec![(msg_eq!(ReadTemperature), msg_ok_return!(ReadTemperature(Celsius(110.0))))],
            ),
            mock_maker.make(
                "Shutdown",
                vec![(
                    msg_eq!(SystemShutdown(ShutdownRequest::Reboot(RebootReason::HighTemperature))),
                    msg_ok_return!(SystemShutdown),
                )],
            ),
            mock_maker.make(
                "Metrics",
                vec![(
                    msg_eq!(LogPlatformMetric(PlatformMetric::ThrottlingResultShutdown)),
                    msg_ok_return!(LogPlatformMetric),
                )],
            ),
        )
        .with_thermal_shutdown_temperature(Celsius(100.0))
        .build(&node_futures)
        .unwrap();

        // Cause the node to enter thermal shutdown
        match executor.run_until_stalled(&mut Box::pin(node.poll_temperature())) {
            futures::task::Poll::Ready(result) => assert!(result.is_ok()),
            e => panic!("{:?}", e),
        };
    }
}
