// 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::dev_control_handler;
use crate::error::PowerManagerError;
use crate::message::{Message, MessageReturn};
use crate::node::Node;
use crate::types::{Farads, Hertz, PState, Volts, Watts};
use crate::utils::connect_to_driver;
use anyhow::{format_err, Context, Error};
use async_trait::async_trait;
use fidl_fuchsia_hardware_cpu_ctrl as fcpuctrl;
use fuchsia_inspect::{self as inspect, Property};
use serde_derive::Deserialize;
use serde_json as json;
use std::cell::Cell;
use std::collections::hash_map::DefaultHasher;
use std::collections::HashMap;
use std::hash::{Hash, Hasher};
use std::rc::Rc;

/// Node: CpuControlHandler
///
/// Summary: Provides a mechanism for controlling the performance state of a CPU domain. The node
///          mostly relies on functionality provided by the DeviceControlHandler node for
///          performance state control, but this node enhances that basic functionality by
///          integrating performance state metadata (CPU P-state information) from the CpuCtrl
///          interface.
///
/// Handles Messages:
///     - SetMaxPowerConsumption
///
/// Sends Messages:
///     - GetCpuLoads
///     - GetPerformanceState
///     - SetPerformanceState
///
/// FIDL dependencies:
///     - fuchsia.hardware.cpu.ctrl.Device: the node uses this protocol to communicate with the
///       CpuCtrl interface of the CPU device specified in the CpuControlHandler constructor

/// Describes the parameters of the CPU domain.
pub struct CpuControlParams {
    /// Available P-states of the CPU. These must be in order of descending power usage, per
    /// section 8.4.6.2 of ACPI spec version 6.3.
    pub p_states: Vec<PState>,
    /// Model capacitance of each CPU core. Required to estimate power usage.
    pub capacitance: Farads,
    /// Logical CPU numbers contained within this CPU domain.
    pub logical_cpu_numbers: Vec<u32>,
}

impl CpuControlParams {
    /// Checks that the list of P-states is valid:
    ///  - Contains at least one element;
    ///  - Is in order of decreasing nominal power consumption.
    fn validate(&self) -> Result<(), Error> {
        if self.logical_cpu_numbers.len() == 0 {
            return Err(format_err!("Must have > 0 CPUs"));
        }
        if !self.logical_cpu_numbers.windows(2).all(|w| w[0] < w[1]) {
            return Err(format_err!("CPUs must be sorted and non-repeating"));
        }
        if self.p_states.len() == 0 {
            return Err(format_err!("Must have at least one P-state"));
        } else if self.p_states.len() > 1 {
            let mut last_power = get_cpu_power(
                self.capacitance,
                self.p_states[0].voltage,
                self.p_states[0].frequency,
            );
            for i in 1..self.p_states.len() {
                let p_state = &self.p_states[i];
                let power = get_cpu_power(self.capacitance, p_state.voltage, p_state.frequency);
                if power >= last_power {
                    return Err(format_err!(
                        "P-states must be in order of decreasing power consumption \
                         (violated by state {})",
                        i
                    ));
                }
                last_power = power;
            }
        }
        Ok(())
    }
}

/// Returns the modeled power consumed by the CPU completing operations at the specified rate.
/// Note that we assume zero static power consumption in this model, and that `op_completion_rate`
/// is only the CPU's clock speed if the CPU is never idle.
pub fn get_cpu_power(capacitance: Farads, voltage: Volts, op_completion_rate: Hertz) -> Watts {
    Watts(capacitance.0 * voltage.0.powi(2) * op_completion_rate.0)
}

/// A builder for constructing the CpuControlHandler node. The fields of this struct are documented
/// as part of the CpuControlHandler struct.
pub struct CpuControlHandlerBuilder<'a> {
    cpu_driver_path: String,
    capacitance: Farads,
    min_cpu_clock_speed: Hertz,
    cpu_stats_handler: Rc<dyn Node>,
    cpu_dev_handler_node: Rc<dyn Node>,
    cpu_ctrl_proxy: Option<fcpuctrl::DeviceProxy>,
    inspect_root: Option<&'a inspect::Node>,
    logical_cpu_numbers: Vec<u32>,
}

impl<'a> CpuControlHandlerBuilder<'a> {
    pub fn new_with_driver_path(
        cpu_driver_path: String,
        // TODO(fxbug.dev/45507): Determine a proper owner for this value.
        capacitance: Farads,
        logical_cpu_numbers: Vec<u32>,
        cpu_stats_handler: Rc<dyn Node>,
        cpu_dev_handler_node: Rc<dyn Node>,
    ) -> Self {
        Self {
            cpu_driver_path,
            capacitance,
            min_cpu_clock_speed: Hertz(0.0),
            logical_cpu_numbers,
            cpu_stats_handler,
            cpu_dev_handler_node,
            cpu_ctrl_proxy: None,
            inspect_root: None,
        }
    }

    #[cfg(test)]
    pub fn new_with_proxy(
        cpu_driver_path: String,
        proxy: fcpuctrl::DeviceProxy,
        capacitance: Farads,
        logical_cpu_numbers: Vec<u32>,
        cpu_stats_handler: Rc<dyn Node>,
        cpu_dev_handler_node: Rc<dyn Node>,
    ) -> Self {
        Self {
            cpu_driver_path,
            cpu_ctrl_proxy: Some(proxy),
            min_cpu_clock_speed: Hertz(0.0),
            capacitance,
            logical_cpu_numbers,
            cpu_stats_handler,
            cpu_dev_handler_node,
            inspect_root: None,
        }
    }

    pub fn new_from_json(json_data: json::Value, nodes: &HashMap<String, Rc<dyn Node>>) -> Self {
        #[derive(Deserialize)]
        struct Config {
            driver_path: String,
            capacitance: f64,
            min_cpu_clock_speed: f64,
            logical_cpu_numbers: Vec<u32>,
        }

        #[derive(Deserialize)]
        struct Dependencies {
            cpu_stats_handler_node: String,
            cpu_dev_handler_node: String,
        }

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

        let data: JsonData = json::from_value(json_data).unwrap();
        Self::new_with_driver_path(
            data.config.driver_path,
            Farads(data.config.capacitance),
            data.config.logical_cpu_numbers,
            nodes[&data.dependencies.cpu_stats_handler_node].clone(),
            nodes[&data.dependencies.cpu_dev_handler_node].clone(),
        )
        .with_min_cpu_clock_speed(Hertz(data.config.min_cpu_clock_speed))
    }

    #[cfg(test)]
    pub fn with_inspect_root(mut self, root: &'a inspect::Node) -> Self {
        self.inspect_root = Some(root);
        self
    }

    pub fn with_min_cpu_clock_speed(mut self, clock_speed: Hertz) -> Self {
        self.min_cpu_clock_speed = clock_speed;
        self
    }

    pub async fn build(self) -> Result<Rc<CpuControlHandler>, Error> {
        // Optionally use the default proxy
        let proxy = if self.cpu_ctrl_proxy.is_none() {
            connect_to_driver::<fcpuctrl::DeviceMarker>(&self.cpu_driver_path)
                .await
                .context("Failed connecting to CPU driver")?
        } else {
            self.cpu_ctrl_proxy.unwrap()
        };

        // Optionally use the default inspect root node
        let inspect_root = self.inspect_root.unwrap_or(inspect::component::inspector().root());
        let inspect_data =
            InspectData::new(inspect_root, format!("CpuControlHandler ({})", self.cpu_driver_path));

        // Query the CPU parameters
        let cpu_control_params = Self::get_cpu_params(
            &self.cpu_driver_path,
            &proxy,
            self.capacitance,
            self.logical_cpu_numbers,
            self.min_cpu_clock_speed,
        )
        .await
        .context("Failed getting CPU params")?;
        inspect_data.set_cpu_control_params(&cpu_control_params);

        let mut hasher = DefaultHasher::new();
        self.cpu_driver_path.hash(&mut hasher);
        let trace_counter_id = hasher.finish();

        let node = Rc::new(CpuControlHandler {
            cpu_driver_path: self.cpu_driver_path,
            cpu_control_params,
            current_p_state_index: Cell::new(0),
            cpu_stats_handler: self.cpu_stats_handler,
            cpu_dev_handler_node: self.cpu_dev_handler_node,
            _cpu_ctrl_proxy: proxy,
            inspect: inspect_data,
            trace_counter_id,
        });

        // Initialize current P-state index
        node.get_current_p_state_index().await?;

        Ok(node)
    }

    /// Query the CPU parameters from the CpuCtrl driver.
    async fn get_cpu_params(
        cpu_driver_path: &String,
        cpu_ctrl_proxy: &fcpuctrl::DeviceProxy,
        capacitance: Farads,
        logical_cpu_numbers: Vec<u32>,
        min_cpu_clock_speed: Hertz,
    ) -> Result<CpuControlParams, Error> {
        fuchsia_trace::duration!(
            "power_manager",
            "CpuControlHandlerBuilder::get_cpu_params",
            "driver" => cpu_driver_path.as_str()
        );

        // Query P-state metadata from the CpuCtrl interface. Each supported performance state
        // has accompanying P-state metadata.
        let mut p_states = Vec::new();
        let mut skipped_p_states = Vec::new();
        for i in 0..dev_control_handler::MAX_PERF_STATES {
            if let Ok(info) = cpu_ctrl_proxy.get_performance_state_info(i).await? {
                let frequency = Hertz(info.frequency_hz as f64);
                let voltage = Volts(info.voltage_uv as f64 / 1e6);
                let p_state = PState { frequency, voltage };

                // Filter out P-states where CPU frequency is unacceptably low
                if frequency >= min_cpu_clock_speed {
                    p_states.push(p_state);
                } else {
                    skipped_p_states.push(p_state);
                }
            } else {
                break;
            }
        }

        let params = CpuControlParams { p_states, logical_cpu_numbers, capacitance };
        params.validate()?;

        fuchsia_trace::instant!(
            "power_manager",
            "CpuControlHandlerBuilder::received_cpu_params",
            fuchsia_trace::Scope::Thread,
            "driver" => cpu_driver_path.as_str(),
            "valid" => 1,
            "p_states" => format!("{:?}", params.p_states).as_str(),
            "capacitance" => params.capacitance.0,
            "logical_cpu_numbers" => format!("{:?}", params.logical_cpu_numbers).as_str(),
            "skipped_p_states" => format!("{:?}", skipped_p_states).as_str()
        );

        Ok(params)
    }
}

pub struct CpuControlHandler {
    /// The path to the driver that this node controls.
    cpu_driver_path: String,

    /// The parameters of the CPU domain which are queried from the CPU driver.
    cpu_control_params: CpuControlParams,

    /// The current CPU P-state index which is queried from the CPU DeviceControlHandler node.
    current_p_state_index: Cell<usize>,

    /// The node which will provide CPU load information. It is expected that this node responds to
    /// the GetCpuLoads message.
    cpu_stats_handler: Rc<dyn Node>,

    /// The node to be used for CPU performance state control. It is expected that this node
    /// responds to the Get/SetPerformanceState messages.
    cpu_dev_handler_node: Rc<dyn Node>,

    /// A proxy handle to communicate with the CPU driver CpuCtrl interface.
    _cpu_ctrl_proxy: fcpuctrl::DeviceProxy,

    /// A struct for managing Component Inspection data
    inspect: InspectData,

    /// Identifies trace counters between CpuControlHandler instances for different drivers.
    trace_counter_id: u64,
}

impl CpuControlHandler {
    /// Returns the total CPU load (averaged since the previous call)
    async fn get_load(&self) -> Result<f32, Error> {
        fuchsia_trace::duration!(
            "power_manager",
            "CpuControlHandler::get_load",
            "driver" => self.cpu_driver_path.as_str()
        );

        // Get load for all CPUs in the system
        let cpu_loads =
            match self.send_message(&self.cpu_stats_handler, &Message::GetCpuLoads).await {
                Ok(MessageReturn::GetCpuLoads(loads)) => Ok(loads),
                Ok(r) => Err(format_err!("GetCpuLoads had unexpected return value: {:?}", r)),
                Err(e) => Err(format_err!("GetCpuLoads failed: {:?}", e)),
            }?;

        // Filter down to only the ones we're concerned with
        Ok(self.cpu_control_params.logical_cpu_numbers.iter().map(|i| cpu_loads[*i as usize]).sum())
    }

    /// Returns the current CPU P-state index
    async fn get_current_p_state_index(&self) -> Result<usize, Error> {
        fuchsia_trace::duration!(
            "power_manager",
            "CpuControlHandler::get_current_p_state_index",
            "driver" => self.cpu_driver_path.as_str()
        );
        match self.send_message(&self.cpu_dev_handler_node, &Message::GetPerformanceState).await {
            Ok(MessageReturn::GetPerformanceState(state)) => Ok(state as usize),
            Ok(r) => Err(format_err!("GetPerformanceState had unexpected return value: {:?}", r)),
            Err(e) => Err(format_err!("GetPerformanceState failed: {:?}", e)),
        }
    }

    /// Sets the P-state to the highest-power state with consumption below `max_power`.
    ///
    /// The estimated power consumption depends on the operation completion rate by the CPU.
    /// We assume that the rate of operations requested over the next sample interval will be
    /// the same as it was over the previous sample interval, up to CPU's max completion rate
    /// for a P-state under consideration.
    async fn handle_set_max_power_consumption(
        &self,
        max_power: &Watts,
    ) -> Result<MessageReturn, PowerManagerError> {
        fuchsia_trace::duration!(
            "power_manager",
            "CpuControlHandler::handle_set_max_power_consumption",
            "driver" => self.cpu_driver_path.as_str(),
            "max_power" => max_power.0
        );

        let current_p_state_index = self.current_p_state_index.get();

        // This is reused several times.
        let num_cores = self.cpu_control_params.logical_cpu_numbers.len() as f64;

        // The operation completion rate over the last sample interval is
        //     num_operations / sample_interval,
        // where
        //     num_operations = last_load * last_frequency * sample_interval.
        // Hence,
        //     last_op_rate = last_load * last_frequency.
        let (last_op_rate, last_max_op_rate) = {
            let last_load = self.get_load().await? as f64;
            self.inspect.last_load.set(last_load);
            fuchsia_trace::counter!(
                "power_manager",
                "CpuControlHandler last_load",
                self.trace_counter_id,
                self.cpu_driver_path.as_str() => last_load
            );

            let last_frequency = self.cpu_control_params.p_states[current_p_state_index].frequency;
            (last_frequency.mul_scalar(last_load), last_frequency.mul_scalar(num_cores))
        };

        self.inspect.last_op_rate.set(last_op_rate.0);
        fuchsia_trace::instant!(
            "power_manager",
            "CpuControlHandler::set_max_power_consumption_data",
            fuchsia_trace::Scope::Thread,
            "driver" => self.cpu_driver_path.as_str(),
            "current_p_state_index" => current_p_state_index as u32,
            "last_op_rate" => last_op_rate.0
        );

        let mut p_state_index = 0;
        let mut estimated_power = Watts(0.0);

        // Iterate through the list of available P-states (guaranteed to be sorted in order of
        // decreasing power consumption) and choose the first that will operate within the
        // `max_power` constraint.
        for (i, state) in self.cpu_control_params.p_states.iter().enumerate() {
            // We assume that the last operation rate carries over to the next interval unless:
            //  - It exceeds the max operation rate at the new frequency, in which case it is
            //    truncated to the new max.
            //  - It is within a small delta of the max rate at the last frequency, in which case we
            //    assume that it would rise to the new maximum if the clock speed were to increase.
            const ESSENTIALLY_MAX_LOAD_FRACTION: f64 = 0.99;
            let new_max_op_rate = state.frequency.mul_scalar(num_cores);
            let estimated_op_rate = if last_op_rate > new_max_op_rate
                || last_op_rate > last_max_op_rate.mul_scalar(ESSENTIALLY_MAX_LOAD_FRACTION)
            {
                new_max_op_rate
            } else {
                last_op_rate
            };

            p_state_index = i;
            estimated_power = get_cpu_power(
                self.cpu_control_params.capacitance,
                state.voltage,
                estimated_op_rate,
            );

            if estimated_power <= *max_power {
                break;
            }
        }

        if p_state_index != current_p_state_index {
            fuchsia_trace::instant!(
                "power_manager",
                "CpuControlHandler::updated_p_state_index",
                fuchsia_trace::Scope::Thread,
                "driver" => self.cpu_driver_path.as_str(),
                "old_index" => current_p_state_index as u32,
                "new_index" => p_state_index as u32
            );

            // Tell the CPU DeviceControlHandler to update the performance state
            self.send_message(
                &self.cpu_dev_handler_node,
                &Message::SetPerformanceState(p_state_index as u32),
            )
            .await?;

            // Cache the new P-state index for calculations on the next iteration
            self.current_p_state_index.set(p_state_index);
            self.inspect.p_state_index.set(p_state_index as u64);
        }

        fuchsia_trace::counter!(
            "power_manager",
            "CpuControlHandler p_state",
            self.trace_counter_id,
            self.cpu_driver_path.as_str() => p_state_index as u32
        );

        Ok(MessageReturn::SetMaxPowerConsumption(estimated_power))
    }
}

#[async_trait(?Send)]
impl Node for CpuControlHandler {
    fn name(&self) -> String {
        format!("CpuControlHandler ({})", self.cpu_driver_path)
    }

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

struct InspectData {
    // Nodes
    root_node: inspect::Node,

    // Properties
    p_state_index: inspect::UintProperty,
    last_op_rate: inspect::DoubleProperty,
    last_load: inspect::DoubleProperty,
}

impl InspectData {
    fn new(parent: &inspect::Node, node_name: String) -> Self {
        // Create a local root node and properties
        let root_node = parent.create_child(node_name);
        let p_state_index = root_node.create_uint("p_state_index", 0);
        let last_op_rate = root_node.create_double("last_op_rate", 0.0);
        let last_load = root_node.create_double("last_load", 0.0);

        InspectData { root_node, p_state_index, last_op_rate, last_load }
    }

    fn set_cpu_control_params(&self, params: &CpuControlParams) {
        let cpu_params_node = self.root_node.create_child("cpu_control_params");

        // Iterate `params.p_states` in reverse order so that the Inspect nodes appear in the same
        // order as the vector (`create_child` inserts nodes at the head).
        for (i, p_state) in params.p_states.iter().enumerate().rev() {
            let p_state_node = cpu_params_node.create_child(format!("p_state_{}", i));
            p_state_node.record_double("voltage (V)", p_state.voltage.0);
            p_state_node.record_double("frequency (Hz)", p_state.frequency.0);

            // Pass ownership of the new P-state node to the parent `cpu_params_node`
            cpu_params_node.record(p_state_node);
        }

        cpu_params_node.record_double("capacitance (F)", params.capacitance.0);
        cpu_params_node.record_string(
            "logical_cpu_numbers",
            format!("{:?}", params.logical_cpu_numbers).as_str(),
        );

        // Pass ownership of the new `cpu_params_node` to the root node
        self.root_node.record(cpu_params_node);
    }
}

#[cfg(test)]
pub mod tests {
    use super::*;
    use crate::test::mock_node::{MessageMatcher, MockNodeMaker};
    use crate::{msg_eq, msg_ok_return};
    use assert_matches::assert_matches;
    use fuchsia_async as fasync;
    use fuchsia_zircon as zx;
    use futures::TryStreamExt;
    use inspect::assert_data_tree;
    use std::collections::HashSet;

    fn setup_fake_service(params: CpuControlParams) -> fcpuctrl::DeviceProxy {
        let (proxy, mut stream) =
            fidl::endpoints::create_proxy_and_stream::<fcpuctrl::DeviceMarker>().unwrap();

        fasync::Task::local(async move {
            while let Ok(req) = stream.try_next().await {
                match req {
                    Some(fcpuctrl::DeviceRequest::GetNumLogicalCores { responder }) => {
                        let _ = responder.send(params.logical_cpu_numbers.len() as u64);
                    }
                    Some(fcpuctrl::DeviceRequest::GetPerformanceStateInfo { state, responder }) => {
                        let index = state as usize;
                        let mut result = if index < params.p_states.len() {
                            Ok(fcpuctrl::CpuPerformanceStateInfo {
                                frequency_hz: params.p_states[index].frequency.0 as i64,
                                voltage_uv: (params.p_states[index].voltage.0 * 1e6) as i64,
                            })
                        } else {
                            Err(zx::Status::NOT_SUPPORTED.into_raw())
                        };
                        let _ = responder.send(&mut result);
                    }
                    _ => assert!(false),
                }
            }
        })
        .detach();

        proxy
    }

    pub async fn setup_test_node(
        params: CpuControlParams,
        cpu_stats_handler: Rc<dyn Node>,
        cpu_dev_handler_node: Rc<dyn Node>,
    ) -> Rc<CpuControlHandler> {
        let capacitance = params.capacitance;
        CpuControlHandlerBuilder::new_with_proxy(
            "Fake".to_string(),
            setup_fake_service(params),
            capacitance,
            vec![0, 1, 2, 3],
            cpu_stats_handler,
            cpu_dev_handler_node,
        )
        .build()
        .await
        .unwrap()
    }

    #[test]
    fn test_get_cpu_power() {
        assert_eq!(get_cpu_power(Farads(100.0e-12), Volts(1.0), Hertz(1.0e9)), Watts(0.1));
    }

    /// Tests that an unsupported message is handled gracefully and an Unsupported error is returned
    #[fasync::run_singlethreaded(test)]
    async fn test_unsupported_msg() {
        let mut mock_maker = MockNodeMaker::new();
        let cpu_ctrl_node = setup_test_node(
            CpuControlParams {
                logical_cpu_numbers: vec![0],
                p_states: vec![PState { frequency: Hertz(0.0), voltage: Volts(0.0) }],
                capacitance: Farads(0.0),
            },
            mock_maker.make("StatsNode", vec![]),
            mock_maker.make(
                "DevHostNode",
                vec![
                    // The CpuControlHandler node queries the current performance state from the
                    // DevHost node during initialization.
                    (msg_eq!(GetPerformanceState), msg_ok_return!(GetPerformanceState(0))),
                ],
            ),
        )
        .await;

        assert_matches!(
            cpu_ctrl_node.handle_message(&Message::ReadTemperature).await,
            Err(PowerManagerError::Unsupported)
        );
    }

    /// Tests that CpuControlParams' `validate` correctly returns an error under invalid inputs.
    #[test]
    fn test_invalid_cpu_params() {
        // Empty CPUs
        assert!(CpuControlParams {
            logical_cpu_numbers: vec![],
            p_states: vec![PState { frequency: Hertz(0.0), voltage: Volts(0.0) }],
            capacitance: Farads(100e-12)
        }
        .validate()
        .is_err());

        // Repeating CPUs
        assert!(CpuControlParams {
            logical_cpu_numbers: vec![0, 0],
            p_states: vec![PState { frequency: Hertz(0.0), voltage: Volts(0.0) }],
            capacitance: Farads(100e-12)
        }
        .validate()
        .is_err());

        // Non-ascending CPUs
        assert!(CpuControlParams {
            logical_cpu_numbers: vec![1, 0],
            p_states: vec![PState { frequency: Hertz(0.0), voltage: Volts(0.0) }],
            capacitance: Farads(100e-12)
        }
        .validate()
        .is_err());

        // Empty p_states
        assert!(CpuControlParams {
            logical_cpu_numbers: vec![0],
            p_states: vec![],
            capacitance: Farads(100e-12)
        }
        .validate()
        .is_err());

        // p_states in order of increasing power usage
        assert!(CpuControlParams {
            logical_cpu_numbers: vec![0],
            p_states: vec![
                PState { frequency: Hertz(1.0), voltage: Volts(1.0) },
                PState { frequency: Hertz(2.0), voltage: Volts(1.0) }
            ],
            capacitance: Farads(100e-12)
        }
        .validate()
        .is_err());

        // p_states with identical power usage
        assert!(CpuControlParams {
            logical_cpu_numbers: vec![0],
            p_states: vec![
                PState { frequency: Hertz(1.0), voltage: Volts(1.0) },
                PState { frequency: Hertz(1.0), voltage: Volts(1.0) }
            ],
            capacitance: Farads(100e-12)
        }
        .validate()
        .is_err());
    }

    async fn get_perf_state(devhost_node: Rc<dyn Node>) -> u32 {
        match devhost_node.handle_message(&Message::GetPerformanceState).await.unwrap() {
            MessageReturn::GetPerformanceState(state) => state,
            e => panic!("Unexpected return value: {:?}", e),
        }
    }

    /// Tests that the SetMaxPowerConsumption message causes the node to correctly consider CPU load
    /// and parameters to choose the appropriate P-states.
    #[fasync::run_singlethreaded(test)]
    async fn test_set_max_power_consumption() {
        let mut mock_maker = MockNodeMaker::new();

        // Arbitrary CpuControlParams chosen to allow the node to demonstrate P-state selection
        let cpu_params = CpuControlParams {
            logical_cpu_numbers: vec![0, 1, 2, 3],
            p_states: vec![
                PState { frequency: Hertz(2.0e9), voltage: Volts(5.0) },
                PState { frequency: Hertz(2.0e9), voltage: Volts(4.0) },
                PState { frequency: Hertz(2.0e9), voltage: Volts(3.0) },
            ],
            capacitance: Farads(100.0e-12),
        };

        // The modeled power consumption at each P-state
        let power_consumption: Vec<Watts> = cpu_params
            .p_states
            .iter()
            .map(|p_state| {
                get_cpu_power(
                    cpu_params.capacitance,
                    p_state.voltage,
                    p_state.frequency.mul_scalar(cpu_params.logical_cpu_numbers.len() as f64),
                )
            })
            .collect();

        let stats_node = mock_maker.make(
            "StatsNode",
            // The CpuControlHandler node queries the current CPU load each time it receives a
            // SetMaxPowerConsumption message
            vec![
                // Make StatsNode give load for more CPUs than we care about to test the filtering
                // logic
                (msg_eq!(GetCpuLoads), msg_ok_return!(GetCpuLoads(vec![1.0; 8]))),
                (msg_eq!(GetCpuLoads), msg_ok_return!(GetCpuLoads(vec![1.0; 8]))),
                (msg_eq!(GetCpuLoads), msg_ok_return!(GetCpuLoads(vec![1.0; 8]))),
            ],
        );
        let devhost_node = mock_maker.make(
            "DevHostNode",
            vec![
                // CpuControlHandler queries performance state during its initialiation
                (msg_eq!(GetPerformanceState), msg_ok_return!(GetPerformanceState(0))),
                // The test queries for current performance state
                (msg_eq!(GetPerformanceState), msg_ok_return!(GetPerformanceState(0))),
                // CpuControlHandler changes performance state to 1
                (msg_eq!(SetPerformanceState(1)), msg_ok_return!(SetPerformanceState)),
                // The test queries for current performance state
                (msg_eq!(GetPerformanceState), msg_ok_return!(GetPerformanceState(1))),
                // CpuControlHandler changes performance state to 2
                (msg_eq!(SetPerformanceState(2)), msg_ok_return!(SetPerformanceState)),
                // The test queries for current performance state
                (msg_eq!(GetPerformanceState), msg_ok_return!(GetPerformanceState(1))),
            ],
        );
        let cpu_ctrl_node = setup_test_node(cpu_params, stats_node, devhost_node.clone()).await;

        // Test case 1: Allow power consumption of the highest P-state; expect to be in P-state 0
        let commanded_power = power_consumption[0].mul_scalar(1.01);
        let expected_power = power_consumption[0];
        assert_matches!(
            cpu_ctrl_node.handle_message(&Message::SetMaxPowerConsumption(commanded_power)).await,
            Ok(MessageReturn::SetMaxPowerConsumption(power)) if power == expected_power
        );
        assert_eq!(get_perf_state(devhost_node.clone()).await, 0);

        // Test case 2: Lower power consumption to that of P-state 1; expect to be in P-state 1
        let commanded_power = power_consumption[1].mul_scalar(1.01);
        let expected_power = power_consumption[1];
        assert_matches!(
            cpu_ctrl_node.handle_message(&Message::SetMaxPowerConsumption(commanded_power)).await,
            Ok(MessageReturn::SetMaxPowerConsumption(power)) if power == expected_power
        );
        assert_eq!(get_perf_state(devhost_node.clone()).await, 1);

        // Test case 3: Reduce the power consumption limit below the lowest P-state; expect to drop
        // to the lowest P-state
        let commanded_power = Watts(0.0);
        let expected_power = power_consumption[2];
        assert_matches!(
            cpu_ctrl_node.handle_message(&Message::SetMaxPowerConsumption(commanded_power)).await,
            Ok(MessageReturn::SetMaxPowerConsumption(power)) if power == expected_power
        );
        assert_eq!(get_perf_state(devhost_node.clone()).await, 1);
    }

    /// Tests that when a minimum CPU clock speed is specified, a P-state with a lower CPU frequency
    /// is never selected.
    #[fasync::run_singlethreaded(test)]
    async fn test_min_cpu_clock_speed() {
        let mut mock_maker = MockNodeMaker::new();

        // Arbitrary CpuControlParams chosen to allow the node to demonstrate P-state selection
        let capacitance = Farads(100.0e-12);
        let cpu_params = CpuControlParams {
            logical_cpu_numbers: vec![0, 1, 2, 3],
            p_states: vec![
                PState { frequency: Hertz(2.0e9), voltage: Volts(3.0) },
                PState { frequency: Hertz(1.0e9), voltage: Volts(3.0) },
                PState { frequency: Hertz(0.5e9), voltage: Volts(3.0) },
            ],
            capacitance,
        };

        // The modeled power consumption at each P-state
        let power_consumption: Vec<Watts> = cpu_params
            .p_states
            .iter()
            .map(|p_state| {
                get_cpu_power(
                    capacitance,
                    p_state.voltage,
                    Hertz(p_state.frequency.0 * cpu_params.logical_cpu_numbers.len() as f64),
                )
            })
            .collect();

        let stats_node = mock_maker.make(
            "StatsNode",
            // The CpuControlHandler node queries the current CPU load each time it receives a
            // SetMaxPowerConsumption message
            vec![
                (msg_eq!(GetCpuLoads), msg_ok_return!(GetCpuLoads(vec![1.0; 4]))),
                (msg_eq!(GetCpuLoads), msg_ok_return!(GetCpuLoads(vec![1.0; 4]))),
            ],
        );
        let devhost_node = mock_maker.make(
            "DevHostNode",
            vec![
                // CpuControlHandler lazy queries performance state during its initialiation
                (msg_eq!(GetPerformanceState), msg_ok_return!(GetPerformanceState(0))),
                // The test queries for current performance state
                (msg_eq!(GetPerformanceState), msg_ok_return!(GetPerformanceState(0))),
                // CpuControlHandler changes performance state to 1
                (msg_eq!(SetPerformanceState(1)), msg_ok_return!(SetPerformanceState)),
                // The test queries for current performance state
                (msg_eq!(GetPerformanceState), msg_ok_return!(GetPerformanceState(1))),
            ],
        );
        let cpu_ctrl_node = CpuControlHandlerBuilder::new_with_proxy(
            "Fake".to_string(),
            setup_fake_service(cpu_params),
            capacitance,
            vec![0, 1, 2, 3],
            stats_node,
            devhost_node.clone(),
        )
        .with_min_cpu_clock_speed(Hertz(1.0e9))
        .build()
        .await
        .unwrap();

        // Test case 1: Allow power consumption of the highest P-state; expect to be in P-state 0
        let commanded_power = power_consumption[0].mul_scalar(1.01);
        let expected_power = power_consumption[0];
        assert_matches!(
            cpu_ctrl_node.handle_message(&Message::SetMaxPowerConsumption(commanded_power)).await,
            Ok(MessageReturn::SetMaxPowerConsumption(power)) if power == expected_power
        );
        assert_eq!(get_perf_state(devhost_node.clone()).await, 0);

        // Test case 2: Reduce power consumption to below the lowest P-state; expect to be in
        // P-state 1 (state 2 should be disallowed).
        let commanded_power = Watts(0.0);
        let expected_power = power_consumption[1];
        assert_matches!(
            cpu_ctrl_node.handle_message(&Message::SetMaxPowerConsumption(commanded_power)).await,
            Ok(MessageReturn::SetMaxPowerConsumption(power)) if power == expected_power
        );
        assert_eq!(get_perf_state(devhost_node.clone()).await, 1);
    }

    /// Tests for the presence and correctness of dynamically-added inspect data
    #[fasync::run_singlethreaded(test)]
    async fn test_inspect_data() {
        let mut mock_maker = MockNodeMaker::new();

        // Some dummy CpuControlParams to verify the params get published in Inspect
        let p_state = PState { frequency: Hertz(2.0e9), voltage: Volts(4.5) };
        let capacitance = Farads(100.0e-12);
        let params = CpuControlParams {
            logical_cpu_numbers: vec![0, 1, 2, 3],
            p_states: vec![p_state],
            capacitance,
        };

        let inspector = inspect::Inspector::new();
        let _node = CpuControlHandlerBuilder::new_with_proxy(
            "Fake".to_string(),
            setup_fake_service(params),
            capacitance,
            vec![0, 1, 2, 3],
            mock_maker.make("StatsNode", vec![]),
            mock_maker.make(
                "DevHostNode",
                vec![
                    // The CpuControlHandler node queries the current performance state from the
                    // DevHost node during initialization.
                    (msg_eq!(GetPerformanceState), msg_ok_return!(GetPerformanceState(0))),
                ],
            ),
        )
        .with_inspect_root(inspector.root())
        .build()
        .await
        .unwrap();

        assert_data_tree!(
            inspector,
            root: {
                "CpuControlHandler (Fake)": contains {
                    cpu_control_params: {
                        "capacitance (F)": capacitance.0,
                        logical_cpu_numbers: "[0, 1, 2, 3]",
                        p_state_0: {
                            "voltage (V)": p_state.voltage.0,
                            "frequency (Hz)": p_state.frequency.0
                        }
                    },
                }
            }
        );
    }

    /// 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": "CpuControlHandler",
            "name": "cpu_control",
            "config": {
                "driver_path": "/dev/class/cpu-ctrl/000",
                "capacitance": 1.2E-10,
                "min_cpu_clock_speed": 1.0e9,
                "logical_cpu_numbers": [0, 1]
            },
            "dependencies": {
                "cpu_stats_handler_node": "cpu_stats",
                "cpu_dev_handler_node": "cpu_dev"
            }
        });

        let mut mock_maker = MockNodeMaker::new();
        let mut nodes: HashMap<String, Rc<dyn Node>> = HashMap::new();
        nodes.insert("cpu_stats".to_string(), mock_maker.make("MockNode", vec![]));
        nodes.insert("cpu_dev".to_string(), mock_maker.make("MockNode", vec![]));
        let _ = CpuControlHandlerBuilder::new_from_json(json_data, &nodes);
    }

    /// Tests that node config files do not contain instances of CpuControlHandler nodes with
    /// overlapping CPU numbers.
    #[test]
    pub fn test_config_files() -> Result<(), anyhow::Error> {
        crate::utils::test_each_node_config_file(|config_file| {
            let cpu_control_handlers =
                config_file.iter().filter(|n| n["type"] == "CpuControlHandler");

            let mut set = HashSet::new();
            for node in cpu_control_handlers {
                for cpu in node["config"]["logical_cpu_numbers"].as_array().unwrap() {
                    let cpu_idx = cpu.as_i64().unwrap();
                    if set.contains(&cpu_idx) {
                        return Err(format_err!("CPU {} already specified", cpu_idx));
                    }

                    set.insert(cpu_idx);
                }
            }

            Ok(())
        })
    }
}
