// 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::LOG_VERBOSITY,
    anyhow::Error,
    fidl::endpoints::Proxy,
    fidl_fuchsia_hardware_power as hpower, fidl_fuchsia_power as fpower, fuchsia_async as fasync,
    fuchsia_syslog::{fx_log_err, fx_vlog},
    fuchsia_zircon as zx,
    futures::{lock::Mutex, TryStreamExt},
    std::sync::{Arc, RwLock},
};

#[derive(Debug, PartialEq)]
enum StatusUpdateResult {
    Notify,
    DoNotNotify,
}

pub(crate) trait BatterySimulationStateObserver {
    fn update_simulation(&self, new_state: bool);
    fn update_simulated_battery_info(&self, battery_info: fpower::BatteryInfo);
}

impl BatterySimulationStateObserver for BatteryManager {
    fn update_simulation(&self, is_simulating: bool) {
        let mut sim_state = self.simulation_state.write().unwrap();
        *sim_state = is_simulating;
        drop(sim_state);
        if !is_simulating {
            self.update_watchers();
        }
    }
    fn update_simulated_battery_info(&self, battery_info: fpower::BatteryInfo) {
        let mut simulated_battery_info = self.simulated_battery_info.write().unwrap();
        *simulated_battery_info = battery_info.clone();
        drop(simulated_battery_info);
        self.update_watchers();
    }
}

/// Core component for the battery manager system.
///
/// BatteryManager maintains the current state info for the battery system
/// as well as the watchers that share this information with subscribed clients.
///
/// simulation_state: true when the simulator is running
pub struct BatteryManager {
    battery_info: RwLock<fpower::BatteryInfo>,
    watchers: Arc<Mutex<Vec<fpower::BatteryInfoWatcherProxy>>>,
    simulation_state: RwLock<bool>,
    simulated_battery_info: RwLock<fpower::BatteryInfo>,
}

#[inline]
fn get_current_time() -> i64 {
    let t = fuchsia_runtime::utc_time();
    (t.into_nanos() / 1000) as i64
}

impl BatteryManager {
    pub fn new() -> BatteryManager {
        BatteryManager {
            battery_info: RwLock::new(fpower::BatteryInfo {
                status: Some(fpower::BatteryStatus::NotAvailable),
                charge_status: Some(fpower::ChargeStatus::Unknown),
                charge_source: Some(fpower::ChargeSource::Unknown),
                level_percent: None,
                level_status: Some(fpower::LevelStatus::Unknown),
                health: Some(fpower::HealthStatus::Unknown),
                time_remaining: Some(fpower::TimeRemaining::Indeterminate(0)),
                timestamp: Some(get_current_time()),
                ..fpower::BatteryInfo::EMPTY
            }),
            watchers: Arc::new(Mutex::new(Vec::new())),
            simulation_state: RwLock::new(false),
            simulated_battery_info: RwLock::new(fpower::BatteryInfo {
                status: Some(fpower::BatteryStatus::NotAvailable),
                charge_status: Some(fpower::ChargeStatus::Unknown),
                charge_source: Some(fpower::ChargeSource::Unknown),
                level_percent: None,
                level_status: Some(fpower::LevelStatus::Unknown),
                health: Some(fpower::HealthStatus::Unknown),
                time_remaining: Some(fpower::TimeRemaining::Indeterminate(0)),
                timestamp: Some(get_current_time()),
                ..fpower::BatteryInfo::EMPTY
            }),
        }
    }

    // Adds watcher
    pub async fn add_watcher(&self, watcher: fpower::BatteryInfoWatcherProxy) {
        let mut watchers = self.watchers.lock().await;
        fx_vlog!(LOG_VERBOSITY, "::manager:: adding watcher: {:?} [{:?}]", watcher, watchers.len());
        watchers.push(watcher)
    }

    // Updates the status
    pub fn update_status(
        &self,
        power_info: hpower::SourceInfo,
        battery_info: Option<hpower::BatteryInfo>,
    ) -> Result<(), anyhow::Error> {
        fx_vlog!(
            LOG_VERBOSITY,
            "update_status with power info: {:#?} and battery info: {:#?}",
            &power_info,
            &battery_info
        );

        match self.update_battery_info(power_info, battery_info) {
            Ok(StatusUpdateResult::Notify) => {
                fx_vlog!(LOG_VERBOSITY, "::manager:: update status changed - NOTIFY");
                let info = self.get_battery_info_copy();
                let watchers = self.watchers.clone();
                fx_vlog!(
                    LOG_VERBOSITY,
                    "::manager:: run watchers {:?} with info {:?}",
                    &watchers,
                    &info
                );
                BatteryManager::run_watchers(watchers.clone(), info.clone());
            }
            Ok(StatusUpdateResult::DoNotNotify) => {
                fx_vlog!(LOG_VERBOSITY, "::manager:: update status unchanged - skipping NOTIFY");
            }
            Err(e) => return Err(e),
        }

        Ok(())
    }

    pub fn run_watchers(
        watchers: Arc<Mutex<Vec<fpower::BatteryInfoWatcherProxy>>>,
        info: fpower::BatteryInfo,
    ) {
        fx_vlog!(LOG_VERBOSITY, "::manager:: run watchers...");
        fasync::Task::spawn(async move {
            let watchers = {
                let mut watchers = watchers.lock().await;
                watchers.retain(|w| !w.is_closed());
                watchers.clone()
            };
            fx_vlog!(LOG_VERBOSITY, "::manager:: run watchers [{:?}]", &watchers.len());
            for w in &watchers {
                if let Err(e) = w.on_change_battery_info(info.clone().into()).await {
                    fx_log_err!("failed to send battery info to watcher {:?}", e);
                }
            }
        })
        .detach()
    }

    fn update_battery_info(
        &self,
        power_info: hpower::SourceInfo,
        battery_info: Option<hpower::BatteryInfo>,
    ) -> Result<StatusUpdateResult, anyhow::Error> {
        let now = get_current_time();
        let old_battery_info = self.get_battery_info_copy();
        fx_vlog!(LOG_VERBOSITY, "::battery_manager:: old battery info: {:?}", &old_battery_info);

        let mut new_battery_info = self.battery_info.write().unwrap();

        // info from AC power source
        if power_info.type_ == hpower::PowerType::Ac {
            // charge status/source
            if power_info.state & hpower::POWER_STATE_CHARGING != 0 {
                new_battery_info.charge_status = Some(fpower::ChargeStatus::Charging);
                if power_info.type_ == hpower::PowerType::Ac {
                    new_battery_info.charge_source = Some(fpower::ChargeSource::AcAdapter);
                } else {
                    //TODO: how to detect USB/Wireless
                    new_battery_info.charge_source = Some(fpower::ChargeSource::Unknown);
                }
            }
        }

        // info from battery power source will include battery info
        if let Some(bi) = battery_info {
            assert!(
                power_info.type_ == hpower::PowerType::Battery,
                "updating battery info with non-battery power source"
            );

            fx_vlog!(
                LOG_VERBOSITY,
                "::battery_manager:: update with hpower info p:{:?} b:{:?}",
                &power_info,
                &bi
            );

            // check battery online and update accordingly
            if power_info.state & hpower::POWER_STATE_ONLINE != 0 {
                new_battery_info.status = Some(fpower::BatteryStatus::Ok);

                // charge status/source
                if power_info.state & hpower::POWER_STATE_CHARGING != 0 {
                    new_battery_info.charge_status = Some(fpower::ChargeStatus::Charging);
                }

                if bi.remaining_capacity == bi.last_full_capacity {
                    new_battery_info.charge_status = Some(fpower::ChargeStatus::Full);
                }

                // level percent
                new_battery_info.level_percent = Some(
                    (bi.remaining_capacity.saturating_mul(100)) as f32
                        / bi.last_full_capacity as f32,
                );

                // level_status
                if power_info.state & hpower::POWER_STATE_CRITICAL != 0 {
                    new_battery_info.level_status = Some(fpower::LevelStatus::Critical);
                } else if bi.remaining_capacity <= bi.capacity_low {
                    new_battery_info.level_status = Some(fpower::LevelStatus::Low);
                } else if bi.remaining_capacity <= bi.capacity_warning {
                    new_battery_info.level_status = Some(fpower::LevelStatus::Warning);
                } else {
                    new_battery_info.level_status = Some(fpower::LevelStatus::Ok);
                }

                // time remaining, provided by hardware as hours
                let nanos_in_one_hour = zx::Duration::from_hours(1);

                if bi.present_rate < 0 {
                    // discharging
                    let remaining_hours =
                        bi.remaining_capacity as f32 / (bi.present_rate.saturating_mul(-1)) as f32;
                    new_battery_info.time_remaining = Some(fpower::TimeRemaining::BatteryLife(
                        (remaining_hours as i64).saturating_mul(nanos_in_one_hour.into_nanos()),
                    ));
                } else {
                    // charging
                    let remaining_hours = (bi.last_full_capacity as f32
                        - bi.remaining_capacity as f32)
                        / (bi.present_rate) as f32;
                    new_battery_info.time_remaining = Some(fpower::TimeRemaining::FullCharge(
                        (remaining_hours as i64).saturating_mul(nanos_in_one_hour.into_nanos()),
                    ));
                }

                // TODO: determine actual battery health
                new_battery_info.health = Some(fpower::HealthStatus::Unknown);
            } else {
                // battery offline/not present
                new_battery_info.status = Some(fpower::BatteryStatus::NotPresent);
            }
        }

        if power_info.state & hpower::POWER_STATE_DISCHARGING != 0 {
            new_battery_info.charge_status = Some(fpower::ChargeStatus::Discharging);
        }

        if (power_info.state & hpower::POWER_STATE_DISCHARGING == 0)
            && (power_info.state & hpower::POWER_STATE_CHARGING == 0)
        {
            new_battery_info.charge_status = Some(fpower::ChargeStatus::NotCharging);
        }

        if new_battery_info.charge_status != Some(fpower::ChargeStatus::Charging)
            && new_battery_info.charge_status != Some(fpower::ChargeStatus::Full)
        {
            new_battery_info.charge_source = Some(fpower::ChargeSource::None);
        }

        if *self.simulation_state.read().unwrap() {
            return Ok(StatusUpdateResult::DoNotNotify);
        }

        match old_battery_info == (*new_battery_info) {
            true => Ok(StatusUpdateResult::DoNotNotify),
            false => {
                new_battery_info.timestamp = Some(now);
                Ok(StatusUpdateResult::Notify)
            }
        }
    }

    pub fn get_battery_info_copy(&self) -> fpower::BatteryInfo {
        if *self.simulation_state.read().unwrap() {
            let info_lock = self.simulated_battery_info.read().unwrap();
            (*info_lock).clone()
        } else {
            let info_lock = self.battery_info.read().unwrap();
            (*info_lock).clone()
        }
    }

    fn update_watchers(&self) {
        let info = self.get_battery_info_copy();
        let watchers = self.watchers.clone();
        BatteryManager::run_watchers(watchers.clone(), info.clone());
    }

    pub fn is_simulating(&self) -> bool {
        *self.simulation_state.read().unwrap()
    }

    pub(crate) async fn serve(
        &self,
        stream: fpower::BatteryManagerRequestStream,
    ) -> Result<(), Error> {
        stream.try_for_each_concurrent(None, move |request| {
            async move {
                match request {
                    fpower::BatteryManagerRequest::GetBatteryInfo { responder, .. } => {
                        let info = self.get_battery_info_copy();
                        fx_vlog!(
                            LOG_VERBOSITY,
                            "::battery_manager_request:: handle GetBatteryInfo request with info: {:?}",
                            &info
                        );
                        responder.send(info)?;

                    }
                    fpower::BatteryManagerRequest::Watch { watcher, .. } => {
                        let watcher = watcher.into_proxy()?;
                        fx_vlog!(LOG_VERBOSITY, "::battery_manager_request:: handle Watch request");
                        self.add_watcher(watcher.clone()).await;

                        // make sure watcher has current battery info
                        let info = self.get_battery_info_copy();

                        fx_vlog!(
                            LOG_VERBOSITY,
                            "::battery_manager_request:: callback on new watcher with info {:?}",
                            &info
                        );
                        watcher.on_change_battery_info(info).await?;
                    }
                }
                Ok(())
            }
        })
        .await?;

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use fidl::endpoints::create_request_stream;
    use fidl_fuchsia_power as fpower;
    use fuchsia_async::futures::TryStreamExt;
    use futures::future::*;

    macro_rules! cmp_fields {
        ($got:ident, $want:ident, [$($field:ident,)*], $test_no:expr) => { $(
            assert_eq!($got.$field, $want.$field, "test no: {}", $test_no);
        )* }
    }

    fn check_status(
        got: &fpower::BatteryInfo,
        want: &fpower::BatteryInfo,
        updated: bool,
        test_no: u32,
    ) {
        if updated {
            cmp_fields!(
                want,
                got,
                [
                    status,
                    charge_status,
                    charge_source,
                    level_percent,
                    level_status,
                    health,
                    time_remaining,
                ],
                test_no
            );
        } else {
            assert_eq!(want, got, "test: {}", test_no);
        }
    }

    fn get_default_battery_info() -> hpower::BatteryInfo {
        let battery_info = hpower::BatteryInfo {
            unit: hpower::BatteryUnit::Ma,
            design_capacity: 5000,
            last_full_capacity: 5000,
            design_voltage: 7000,
            capacity_warning: 700,
            capacity_low: 500,
            capacity_granularity_low_warning: 1,
            capacity_granularity_warning_full: 1,
            present_rate: -500,
            remaining_capacity: 3000,
            present_voltage: 7000,
        };
        return battery_info;
    }

    #[fuchsia_async::run_until_stalled(test)]
    async fn test_run_watcher() {
        let battery_manager = BatteryManager::new();
        let mut battery_info: fpower::BatteryInfo = battery_manager.get_battery_info_copy();
        battery_info.level_percent = Some(50.0);

        let (watcher_client_end, mut stream) =
            create_request_stream::<fpower::BatteryInfoWatcherMarker>().unwrap();
        let watcher = watcher_client_end.into_proxy().unwrap();

        let watchers = Arc::new(Mutex::new(vec![watcher]));

        let serve_fut = async move {
            let request = stream.try_next().await.unwrap();
            if let Some(fpower::BatteryInfoWatcherRequest::OnChangeBatteryInfo {
                info,
                responder,
            }) = request
            {
                let level = info.level_percent.unwrap().round() as u8;
                assert_eq!(level, 50);
                responder.send().unwrap();
            } else {
                panic!("Unexpected message received");
            };
        };
        let request_fut = async move {
            BatteryManager::run_watchers(watchers, battery_info);
        };

        join(serve_fut, request_fut).await;
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_run_watchers_channel_closed() {
        let battery_manager = BatteryManager::new();
        let mut battery_info: fpower::BatteryInfo = battery_manager.get_battery_info_copy();
        battery_info.level_percent = Some(50.0);

        let (watcher1_client_end, mut stream1) =
            create_request_stream::<fpower::BatteryInfoWatcherMarker>().unwrap();
        let watcher1 = watcher1_client_end.into_proxy().unwrap();

        let (watcher2_client_end, mut stream2) =
            create_request_stream::<fpower::BatteryInfoWatcherMarker>().unwrap();
        let watcher2 = watcher2_client_end.into_proxy().unwrap();

        let watchers = Arc::new(Mutex::new(vec![watcher1, watcher2]));

        let serve1_fut = async move {
            // first request should match first change notification sent
            // at 50%
            let request = stream1.try_next().await.unwrap();
            if let Some(fpower::BatteryInfoWatcherRequest::OnChangeBatteryInfo {
                info,
                responder,
            }) = request
            {
                let level = info.level_percent.unwrap().round() as u8;
                assert_eq!(level, 50);
                responder.send().unwrap();
            } else {
                panic!("Unexpected message received");
            };
            // second should match subsequent notification at 60%
            let request = stream1.try_next().await.unwrap();
            if let Some(fpower::BatteryInfoWatcherRequest::OnChangeBatteryInfo {
                info,
                responder,
            }) = request
            {
                let level = info.level_percent.unwrap().round() as u8;
                assert_eq!(level, 60);
                responder.send().unwrap();
            } else {
                panic!("Unexpected message received");
            };
        };

        let serve2_fut = async move {
            // first request should match first change notification sent
            // at 50%
            let request = stream2.try_next().await.unwrap();
            if let Some(fpower::BatteryInfoWatcherRequest::OnChangeBatteryInfo {
                info,
                responder,
            }) = request
            {
                let level = info.level_percent.unwrap().round() as u8;
                assert_eq!(level, 50);
                // but then we drop the channel...
                std::mem::drop(responder);
            } else {
                panic!("Unexpected message received");
            };
            // should not get the second...
            if let Some(_) = stream2.try_next().await.unwrap() {
                panic!("Unexpected message, channel should be closed");
            }
        };

        let request_fut = async move {
            BatteryManager::run_watchers(watchers.clone(), battery_info.clone());
            battery_info.level_percent = Some(60.0);
            BatteryManager::run_watchers(watchers, battery_info);
        };

        join3(serve1_fut, serve2_fut, request_fut).await;
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn update_battery_info() {
        let nanos_in_one_hour = zx::Duration::from_hours(1);

        let battery_manager = BatteryManager::new();
        let mut power_info = hpower::SourceInfo { type_: hpower::PowerType::Ac, state: 1 };

        // state: ac powered, with no battery info to update
        let mut want = battery_manager.get_battery_info_copy();
        want.status = Some(fpower::BatteryStatus::NotAvailable);
        want.charge_source = Some(fpower::ChargeSource::None);
        want.charge_status = Some(fpower::ChargeStatus::NotCharging);
        want.level_percent = None;
        let _ = battery_manager.update_battery_info(power_info.clone(), None);
        check_status(&battery_manager.get_battery_info_copy(), &want, true, 1);

        // state: unchanged
        let want = battery_manager.get_battery_info_copy();
        let result = battery_manager.update_battery_info(power_info.clone(), None);
        assert_eq!(result.unwrap(), StatusUpdateResult::DoNotNotify);
        check_status(&battery_manager.get_battery_info_copy(), &want, false, 2);

        // state: battery powered, discharging
        power_info.type_ = hpower::PowerType::Battery;
        power_info.state = 0x3; // ONLINE | DISCHARGING
        let mut want = battery_manager.get_battery_info_copy();
        want.status = Some(fpower::BatteryStatus::Ok);
        want.charge_status = Some(fpower::ChargeStatus::Discharging);
        want.charge_source = Some(fpower::ChargeSource::None);
        want.level_status = Some(fpower::LevelStatus::Ok);
        want.level_percent = Some((3000.0 * 100.0) / 5000.0);
        want.time_remaining =
            Some(fpower::TimeRemaining::BatteryLife(6 * nanos_in_one_hour.into_nanos()));
        let mut battery_info = get_default_battery_info();
        let result =
            battery_manager.update_battery_info(power_info.clone(), Some(battery_info.clone()));
        assert_eq!(result.unwrap(), StatusUpdateResult::Notify);
        check_status(&battery_manager.get_battery_info_copy(), &want, true, 3);

        // state: battery powered, discharging/warning
        power_info.state = 0x3; // ONLINE | DISCHARGING
        battery_info.remaining_capacity = 700;
        let mut want = battery_manager.get_battery_info_copy();
        want.status = Some(fpower::BatteryStatus::Ok);
        want.charge_status = Some(fpower::ChargeStatus::Discharging);
        want.charge_source = Some(fpower::ChargeSource::None);
        want.level_status = Some(fpower::LevelStatus::Warning);
        want.level_percent = Some((700.0 * 100.0) / 5000.0);
        want.time_remaining =
            Some(fpower::TimeRemaining::BatteryLife(nanos_in_one_hour.into_nanos()));
        let _ = battery_manager.update_battery_info(power_info.clone(), Some(battery_info.clone()));
        check_status(&battery_manager.get_battery_info_copy(), &want, true, 4);

        // state: battery powered, discharging/low
        power_info.state = 0x3; // ONLINE | DISCHARGING
        battery_info.remaining_capacity = 500;
        let mut want = battery_manager.get_battery_info_copy();
        want.status = Some(fpower::BatteryStatus::Ok);
        want.charge_status = Some(fpower::ChargeStatus::Discharging);
        want.charge_source = Some(fpower::ChargeSource::None);
        want.level_status = Some(fpower::LevelStatus::Low);
        want.level_percent = Some((500.0 * 100.0) / 5000.0);
        want.time_remaining =
            Some(fpower::TimeRemaining::BatteryLife(nanos_in_one_hour.into_nanos()));
        let _ = battery_manager.update_battery_info(power_info.clone(), Some(battery_info.clone()));
        check_status(&battery_manager.get_battery_info_copy(), &want, true, 5);

        // state: battery powered, discharging/critical
        power_info.state = 0xB; // ONLINE | DISCHARGING | CRITICAL
        let mut want = battery_manager.get_battery_info_copy();
        want.status = Some(fpower::BatteryStatus::Ok);
        want.charge_status = Some(fpower::ChargeStatus::Discharging);
        want.charge_source = Some(fpower::ChargeSource::None);
        want.level_status = Some(fpower::LevelStatus::Critical);
        let _ = battery_manager.update_battery_info(power_info.clone(), Some(battery_info.clone()));
        check_status(&battery_manager.get_battery_info_copy(), &want, true, 6);

        // state: battery charging via AC
        power_info.type_ = hpower::PowerType::Ac;
        power_info.state = 0x5; // ONLINE | CHARGING
        let _ = battery_manager.update_battery_info(power_info.clone(), None);
        power_info.type_ = hpower::PowerType::Battery;
        power_info.state = 0x5; // ONLINE | CHARGING
        battery_info.present_rate = 1000;
        battery_info.remaining_capacity = 3000;
        let mut want = battery_manager.get_battery_info_copy();
        want.status = Some(fpower::BatteryStatus::Ok);
        want.charge_status = Some(fpower::ChargeStatus::Charging);
        want.charge_source = Some(fpower::ChargeSource::AcAdapter);
        want.level_status = Some(fpower::LevelStatus::Ok);
        want.level_percent = Some((3000.0 * 100.0) / 5000.0);
        want.time_remaining =
            Some(fpower::TimeRemaining::FullCharge(2 * nanos_in_one_hour.into_nanos()));
        let _ = battery_manager.update_battery_info(power_info.clone(), Some(battery_info.clone()));
        check_status(&battery_manager.get_battery_info_copy(), &want, true, 7);

        // state: battery charging via AC/level critical
        power_info.type_ = hpower::PowerType::Ac;
        power_info.state = 0xD; // ONLINE | CHARGING | CRITICAL
        let _ = battery_manager.update_battery_info(power_info.clone(), None);
        power_info.type_ = hpower::PowerType::Battery;
        power_info.state = 0xD; // ONLINE | CHARGING | CRITICAL
        let mut want = battery_manager.get_battery_info_copy();
        want.status = Some(fpower::BatteryStatus::Ok);
        want.charge_status = Some(fpower::ChargeStatus::Charging);
        want.charge_source = Some(fpower::ChargeSource::AcAdapter);
        want.level_status = Some(fpower::LevelStatus::Critical);
        let _ = battery_manager.update_battery_info(power_info.clone(), Some(battery_info.clone()));
        check_status(&battery_manager.get_battery_info_copy(), &want, true, 8);

        // state: battery charging via AC/level full
        power_info.state = 0x5; // ONLINE | CHARGING
        battery_info.remaining_capacity = 5000;
        let mut want = battery_manager.get_battery_info_copy();
        want.status = Some(fpower::BatteryStatus::Ok);
        want.charge_status = Some(fpower::ChargeStatus::Full);
        want.charge_source = Some(fpower::ChargeSource::AcAdapter);
        want.level_status = Some(fpower::LevelStatus::Ok);
        want.level_percent = Some(100.0);
        want.time_remaining = Some(fpower::TimeRemaining::FullCharge(0));
        let _ = battery_manager.update_battery_info(power_info.clone(), Some(battery_info.clone()));
        check_status(&battery_manager.get_battery_info_copy(), &want, true, 9);

        // state: battery charging via AC/extreme values (check overflow)
        power_info.state = 0x5; // ONLINE | CHARGING
        battery_info.last_full_capacity = u32::max_value();
        battery_info.remaining_capacity = u32::min_value();
        battery_info.present_rate = 1;
        let mut want = battery_manager.get_battery_info_copy();
        want.status = Some(fpower::BatteryStatus::Ok);
        want.charge_status = Some(fpower::ChargeStatus::Charging);
        want.charge_source = Some(fpower::ChargeSource::AcAdapter);
        want.level_status = Some(fpower::LevelStatus::Low);
        want.level_percent = Some(0.0);
        want.time_remaining = Some(fpower::TimeRemaining::FullCharge(i64::max_value()));
        let _ = battery_manager.update_battery_info(power_info.clone(), Some(battery_info.clone()));
        check_status(&battery_manager.get_battery_info_copy(), &want, true, 10);
    }
}
