// 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::backlight::BacklightControl;
use crate::sender_channel::SenderChannel;
use crate::sensor::SensorControl;
use async_trait::async_trait;
use std::cmp;
use std::sync::Arc;

use anyhow::{format_err, Error};
use fidl_fuchsia_ui_brightness::{
    ControlRequest as BrightnessControlRequest, ControlWatchAutoBrightnessAdjustmentResponder,
    ControlWatchAutoBrightnessResponder, ControlWatchCurrentBrightnessResponder,
};
use fuchsia_async::{self as fasync, DurationExt};
use fuchsia_syslog::{self, fx_log_err, fx_log_info};
use fuchsia_zircon::sys::ZX_ERR_NOT_SUPPORTED;
use fuchsia_zircon::{Duration, DurationNum};
use futures::channel::mpsc::UnboundedSender;
use futures::future::{AbortHandle, Abortable};
use futures::lock::Mutex;
use futures::prelude::*;
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
use serde_json;
use splines::{Interpolation, Key, Spline};
use std::{fs, io};
use watch_handler::{Sender, WatchHandler};

// Delay between sensor reads
const SLOW_SCAN_TIMEOUT_MS: i64 = 2000;
// Delay if we have made a large change in auto brightness
const QUICK_SCAN_TIMEOUT_MS: i64 = 100;
// What constitutes a large change in brightness?
// This seems small but it is significant and works nicely.
const LARGE_CHANGE_THRESHOLD_NITS: i32 = 0.016 as i32;
const AUTO_MINIMUM_BRIGHTNESS: f32 = 0.004;
const BRIGHTNESS_USER_MULTIPLIER_CENTER: f32 = 1.0;
const BRIGHTNESS_USER_MULTIPLIER_MAX: f32 = 8.0;
const BRIGHTNESS_USER_MULTIPLIER_MIN: f32 = 0.25;
const BRIGHTNESS_TABLE_FILE_PATH: &str = "/data/brightness_table";

// Gives pleasing, smooth brightness ramp up and down
const BRIGHTNESS_STEP_SIZE: f32 = 0.001;
// Time between brightness steps. Any longer than this and the screen noticeably shimmers
const MAX_BRIGHTNESS_STEP_TIME_MS: i64 = 100;
// Brightness changes should take this time unless we exceed the MAX_BRIGHTNESS_STEP_TIME
const BRIGHTNESS_CHANGE_DURATION_MS: i64 = 2000;

#[derive(Serialize, Deserialize, Clone)]
struct BrightnessPoint {
    ambient_lux: f32,
    display_nits: f32,
}

#[derive(Serialize, Deserialize, Clone)]
struct BrightnessTable {
    points: Vec<BrightnessPoint>,
}

impl From<fidl_fuchsia_ui_brightness::BrightnessPoint> for BrightnessPoint {
    fn from(brightness_point: fidl_fuchsia_ui_brightness::BrightnessPoint) -> Self {
        return BrightnessPoint {
            ambient_lux: brightness_point.ambient_lux,
            display_nits: brightness_point.display_nits,
        };
    }
}

impl From<fidl_fuchsia_ui_brightness::BrightnessTable> for BrightnessTable {
    fn from(brightness_table: fidl_fuchsia_ui_brightness::BrightnessTable) -> Self {
        let fidl_fuchsia_ui_brightness::BrightnessTable { points } = brightness_table;
        return BrightnessTable { points: points.into_iter().map(|p| p.into()).collect() };
    }
}

//This is the default table, and a default curve will be generated base on this table.
//This will be replaced once SetBrightnessTable is called.
lazy_static! {
    static ref BRIGHTNESS_TABLE: Arc<Mutex<BrightnessTable>> = {
        let mut lux_to_nits = Vec::new();
        lux_to_nits.push(BrightnessPoint { ambient_lux: 0., display_nits: 0. });
        lux_to_nits.push(BrightnessPoint { ambient_lux: 10., display_nits: 3.33 });
        lux_to_nits.push(BrightnessPoint { ambient_lux: 30., display_nits: 8.7 });
        lux_to_nits.push(BrightnessPoint { ambient_lux: 60., display_nits: 18.27 });
        lux_to_nits.push(BrightnessPoint { ambient_lux: 100., display_nits: 32.785 });
        lux_to_nits.push(BrightnessPoint { ambient_lux: 150., display_nits: 36.82 });
        lux_to_nits.push(BrightnessPoint { ambient_lux: 210., display_nits: 75.0 });
        lux_to_nits.push(BrightnessPoint { ambient_lux: 250., display_nits: 124.16 });
        lux_to_nits.push(BrightnessPoint { ambient_lux: 300., display_nits: 162.96 });
        lux_to_nits.push(BrightnessPoint { ambient_lux: 340., display_nits: 300. });
        Arc::new(Mutex::new(BrightnessTable { points: lux_to_nits }))
    };
}

lazy_static! {
    static ref AUTO_BRIGHTNESS_ADJUSTMENT: Arc<Mutex<f32>> = Arc::new(Mutex::new(1.0));
    static ref GET_BRIGHTNESS_FAILED_FIRST: Arc<Mutex<bool>> = Arc::new(Mutex::new(true));
    static ref LAST_SET_BRIGHTNESS: Arc<Mutex<f32>> = Arc::new(Mutex::new(1.0));
    static ref BRIGHTNESS_CHANGE_DURATION: Arc<Mutex<Duration>> =
        Arc::new(Mutex::new(BRIGHTNESS_CHANGE_DURATION_MS.millis()));
}

pub struct WatcherCurrentResponder {
    watcher_current_responder: ControlWatchCurrentBrightnessResponder,
}

impl Sender<f32> for WatcherCurrentResponder {
    fn send_response(self, data: f32) {
        if let Err(e) = self.watcher_current_responder.send(data) {
            fx_log_err!("Failed to reply to WatchCurrentBrightness: {}", e);
        }
    }
}

pub struct WatcherAutoResponder {
    watcher_auto_responder: ControlWatchAutoBrightnessResponder,
}

impl Sender<bool> for WatcherAutoResponder {
    fn send_response(self, data: bool) {
        if let Err(e) = self.watcher_auto_responder.send(data) {
            fx_log_err!("Failed to reply to WatchAutoBrightness: {}", e);
        }
    }
}

pub struct WatcherAdjustmentResponder {
    watcher_adjustment_responder: ControlWatchAutoBrightnessAdjustmentResponder,
}

impl Sender<f32> for WatcherAdjustmentResponder {
    fn send_response(self, data: f32) {
        if let Err(e) = self.watcher_adjustment_responder.send(data) {
            fx_log_err!("Failed to reply to WatchAutoBrightnessAdjustment: {}", e);
        }
    }
}

pub struct Control {
    sensor: Arc<Mutex<dyn SensorControl>>,
    backlight: Arc<Mutex<dyn BacklightControl>>,
    set_brightness_abort_handle: Arc<Mutex<Option<AbortHandle>>>,
    auto_brightness_abort_handle: Option<AbortHandle>,
    spline: Spline<f32, f32>,
    current_sender_channel: Arc<Mutex<SenderChannel<f32>>>,
    auto_sender_channel: Arc<Mutex<SenderChannel<bool>>>,
    adjustment_sender_channel: Arc<Mutex<SenderChannel<f32>>>,
}

impl Control {
    pub async fn new(
        sensor: Arc<Mutex<dyn SensorControl>>,
        backlight: Arc<Mutex<dyn BacklightControl>>,
        current_sender_channel: Arc<Mutex<SenderChannel<f32>>>,
        auto_sender_channel: Arc<Mutex<SenderChannel<bool>>>,
        adjustment_sender_channel: Arc<Mutex<SenderChannel<f32>>>,
    ) -> Control {
        fx_log_info!("New Control class");

        let set_brightness_abort_handle = Arc::new(Mutex::new(None::<AbortHandle>));
        let default_table_points = &*BRIGHTNESS_TABLE.lock().await.points;
        let brightness_table = read_brightness_table_file(BRIGHTNESS_TABLE_FILE_PATH)
            .unwrap_or_else(|e| {
                fx_log_err!("Error occurred when trying to read existing settings: {}, using default table instead.", e);
                BrightnessTable { points: default_table_points.to_vec() }
            });

        let spline = generate_spline(&brightness_table);

        let auto_brightness_abort_handle = None::<AbortHandle>;
        let mut result = Control {
            backlight,
            sensor,
            set_brightness_abort_handle,
            auto_brightness_abort_handle,
            spline,
            current_sender_channel,
            auto_sender_channel,
            adjustment_sender_channel,
        };
        // Startup auto-brightness loop
        result.start_auto_brightness_task();
        result
    }

    pub async fn handle_request(
        &mut self,
        request: BrightnessControlRequest,
        watch_current_handler: Arc<Mutex<WatchHandler<f32, WatcherCurrentResponder>>>,
        watch_auto_handler: Arc<Mutex<WatchHandler<bool, WatcherAutoResponder>>>,
        watch_adjustment_handler: Arc<Mutex<WatchHandler<f32, WatcherAdjustmentResponder>>>,
    ) {
        // TODO(kpt): "Consider adding additional tests against the resulting FIDL service itself so
        // that you can ensure it continues serving clients correctly."
        match request {
            BrightnessControlRequest::SetAutoBrightness { control_handle: _ } => {
                self.set_auto_brightness().await;
            }
            BrightnessControlRequest::WatchAutoBrightness { responder } => {
                let watch_auto_result =
                    self.watch_auto_brightness(watch_auto_handler, responder).await;
                match watch_auto_result {
                    Ok(_v) => {}
                    Err(e) => fx_log_err!("Watch auto brightness failed due to err {}.", e),
                }
            }
            BrightnessControlRequest::SetManualBrightness { value, control_handle: _ } => {
                let value = num_traits::clamp(value, 0.0, 1.0);
                self.set_manual_brightness(value).await;
            }
            BrightnessControlRequest::SetManualBrightnessSmooth {
                value,
                duration,
                control_handle: _,
            } => {
                self.set_manual_brightness_smooth(value, duration).await;
            }
            BrightnessControlRequest::WatchCurrentBrightness { responder } => {
                let watch_current_result =
                    self.watch_current_brightness(watch_current_handler, responder).await;
                match watch_current_result {
                    Ok(_v) => {}
                    Err(e) => fx_log_err!("Watch current brightness failed due to err {}.", e),
                }
            }
            BrightnessControlRequest::SetBrightnessTable { table, control_handle: _ } => {
                let result = self.check_brightness_table_and_set_new_curve(&table.into()).await;
                match result {
                    Ok(_v) => fx_log_info!("Brightness table is valid and set"),
                    Err(e) => {
                        // TODO(lingxueluo): Close the connection if brightness table not valid.
                        fx_log_err!("Brightness table is not valid because {}", e);
                    }
                }
            }

            BrightnessControlRequest::SetAutoBrightnessAdjustment {
                adjustment,
                control_handle: _,
            } => {
                self.scale_new_adjustment(adjustment).await;
            }
            BrightnessControlRequest::WatchAutoBrightnessAdjustment { responder } => {
                let watch_adjustment_result = self
                    .watch_auto_brightness_adjustment(watch_adjustment_handler, responder)
                    .await;
                match watch_adjustment_result {
                    Ok(_v) => {}
                    Err(e) => fx_log_err!("Watch adjustment failed due to err {}.", e),
                }
            }
            BrightnessControlRequest::GetMaxAbsoluteBrightness { responder } => {
                let result = self.get_max_absolute_brightness();
                match result.await {
                    Ok(value) => {
                        if let Err(e) = responder.send(&mut Ok(value)) {
                            fx_log_err!("Failed to reply to GetMaxAbsoluteBrightness: {}", e);
                        }
                    }
                    Err(e) => {
                        fx_log_err!("Failed to get max absolute brightness: {}", e);

                        if let Err(e) = responder.send(&mut Err(ZX_ERR_NOT_SUPPORTED)) {
                            fx_log_err!("Failed to reply to GetMaxAbsoluteBrightness: {}", e);
                        }
                    }
                }
            }
        }
    }

    pub async fn add_current_sender_channel(&mut self, sender: UnboundedSender<f32>) {
        self.current_sender_channel.lock().await.add_sender_channel(sender).await;
    }

    pub async fn add_auto_sender_channel(&mut self, sender: UnboundedSender<bool>) {
        self.auto_sender_channel.lock().await.add_sender_channel(sender).await;
    }

    pub async fn add_adjustment_sender_channel(&mut self, sender: UnboundedSender<f32>) {
        self.adjustment_sender_channel.lock().await.add_sender_channel(sender).await;
    }

    pub fn get_backlight_and_auto_brightness_on(
        &mut self,
    ) -> (Arc<Mutex<dyn BacklightControl>>, bool) {
        (self.backlight.clone(), self.auto_brightness_abort_handle.is_some())
    }

    // FIDL message handlers
    async fn set_auto_brightness(&mut self) {
        if self.auto_brightness_abort_handle.is_none() {
            fx_log_info!("Auto-brightness turned on");
            self.start_auto_brightness_task();
            self.auto_sender_channel
                .lock()
                .await
                .send_value(self.auto_brightness_abort_handle.is_some());
        }
    }

    async fn watch_auto_brightness(
        &mut self,
        watch_auto_handler: Arc<Mutex<WatchHandler<bool, WatcherAutoResponder>>>,
        responder: ControlWatchAutoBrightnessResponder,
    ) -> Result<(), Error> {
        let mut hanging_get_lock = watch_auto_handler.lock().await;
        hanging_get_lock.watch(WatcherAutoResponder { watcher_auto_responder: responder })?;
        Ok(())
    }

    fn start_auto_brightness_task(&mut self) {
        if let Some(handle) = &self.auto_brightness_abort_handle.take() {
            handle.abort();
        }
        let backlight = self.backlight.clone();
        let sensor = self.sensor.clone();
        let set_brightness_abort_handle = self.set_brightness_abort_handle.clone();
        let current_sender_channel = self.current_sender_channel.clone();
        let spline = self.spline.clone();
        let (abort_handle, abort_registration) = AbortHandle::new_pair();
        fasync::Task::spawn(
            Abortable::new(
                async move {
                    let backlight = backlight.clone();
                    let max_brightness = {
                        let backlight = backlight.clone();
                        let backlight = backlight.lock().await;
                        let max_result = backlight.get_max_absolute_brightness();
                        match max_result.await {
                            Ok(max_value) => max_value,
                            Err(_e) => 250.0,
                        }
                    };
                    // initialize to an impossible number
                    let mut last_value: i32 = -1;
                    loop {
                        let current_sender_channel = current_sender_channel.clone();
                        let sensor = sensor.clone();
                        let mut value =
                            read_sensor_and_get_brightness(sensor, &spline, max_brightness).await;
                        let adjustment = *AUTO_BRIGHTNESS_ADJUSTMENT.lock().await;
                        value = num_traits::clamp(value * adjustment, AUTO_MINIMUM_BRIGHTNESS, 1.0);
                        set_brightness(
                            value,
                            set_brightness_abort_handle.clone(),
                            backlight.clone(),
                            current_sender_channel,
                        )
                        .await;
                        let large_change =
                            (last_value as i32 - value as i32).abs() > LARGE_CHANGE_THRESHOLD_NITS;
                        last_value = value as i32;
                        let delay_timeout =
                            if large_change { QUICK_SCAN_TIMEOUT_MS } else { SLOW_SCAN_TIMEOUT_MS };
                        fuchsia_async::Timer::new(Duration::from_millis(delay_timeout).after_now())
                            .await;
                    }
                },
                abort_registration,
            )
            .unwrap_or_else(|_| ()),
        )
        .detach();
        self.auto_brightness_abort_handle = Some(abort_handle);
    }

    async fn set_manual_brightness(&mut self, value: f32) {
        if let Some(handle) = self.auto_brightness_abort_handle.take() {
            fx_log_info!("Auto-brightness off, brightness set to {}", value);
            handle.abort();
        }
        self.auto_sender_channel.lock().await.send_value(false);
        let current_sender_channel = self.current_sender_channel.clone();
        set_brightness(
            value,
            self.set_brightness_abort_handle.clone(),
            self.backlight.clone(),
            current_sender_channel,
        )
        .await;
    }

    async fn set_manual_brightness_smooth(&mut self, value: f32, duration: i64) {
        let duration_nanos = Duration::from_nanos(duration);
        *BRIGHTNESS_CHANGE_DURATION.lock().await = duration_nanos.into_millis().millis();
        let value = num_traits::clamp(value, 0.0, 1.0);
        self.set_manual_brightness(value).await;
    }

    async fn watch_current_brightness(
        &mut self,
        watch_current_handler: Arc<Mutex<WatchHandler<f32, WatcherCurrentResponder>>>,
        responder: ControlWatchCurrentBrightnessResponder,
    ) -> Result<(), Error> {
        let mut hanging_get_lock = watch_current_handler.lock().await;
        hanging_get_lock.watch(WatcherCurrentResponder { watcher_current_responder: responder })?;
        Ok(())
    }

    async fn set_brightness_curve(&mut self, table: &BrightnessTable) {
        fx_log_info!("Setting new brightness curve.");
        self.spline = generate_spline(table);

        self.start_auto_brightness_task();

        let result = self.store_brightness_table(table, BRIGHTNESS_TABLE_FILE_PATH);
        match result {
            Ok(_v) => fx_log_info!("Stored successfully"),
            Err(e) => fx_log_info!("Didn't store successfully due to error {}", e),
        }
    }

    fn store_brightness_table(
        &mut self,
        table: &BrightnessTable,
        file_path: &str,
    ) -> Result<(), Error> {
        fx_log_info!("Storing brightness table set.");
        let file = fs::File::create(file_path)?;
        serde_json::to_writer(io::BufWriter::new(file), &table)
            .map_err(|e| anyhow::format_err!("Failed to write to file, ran into error: {:?}", e))
    }

    async fn check_brightness_table_and_set_new_curve(
        &mut self,
        table: &BrightnessTable,
    ) -> Result<(), Error> {
        let BrightnessTable { points } = table;
        if points.is_empty() {
            fx_log_info!("Brightness table can not be empty, use the default table instead.");
            let BrightnessTable { points } = &*BRIGHTNESS_TABLE.lock().await;
            let brightness_table = BrightnessTable { points: points.to_vec() };
            self.set_brightness_curve(&brightness_table).await;
            return Ok(());
        }
        let mut last_lux = -1.0;
        for brightness_point in points {
            if brightness_point.ambient_lux < 0.0 || brightness_point.display_nits < 0.0 {
                fx_log_info!("Lux or nits in this table is negative.");
                return Err(format_err!(format!("Lux or nits in this table is negative.")));
            }
            if brightness_point.ambient_lux > last_lux {
                last_lux = brightness_point.ambient_lux;
            } else {
                fx_log_info!("Not increasing lux in this table.");
                return Err(format_err!(format!("Not increasing lux in this table.")));
            }
        }
        self.set_brightness_curve(&table).await;
        Ok(())
    }

    async fn scale_new_adjustment(&mut self, mut adjustment: f32) -> f32 {
        self.adjustment_sender_channel.lock().await.send_value(adjustment);
        // |adjustment| ranges from [-1.0, 1.0]
        // Default adjustment is 0.0, map that to x1.0
        if adjustment >= 0.0 {
            // Map from [0.0, 1.0] to [BRIGHTNESS_USER_MULTIPLIER_CENTER,
            // BRIGHTNESS_USER_MULTIPLIER_MAX]
            adjustment = adjustment
                * (BRIGHTNESS_USER_MULTIPLIER_MAX - BRIGHTNESS_USER_MULTIPLIER_CENTER)
                + BRIGHTNESS_USER_MULTIPLIER_CENTER;
        } else {
            // Map from [-1.0, 0.0) to [BRIGHTNESS_USER_MULTIPLIER_MIN,
            // BRIGHTNESS_USER_MULTIPLIER_CENTER)
            adjustment = adjustment
                * (BRIGHTNESS_USER_MULTIPLIER_CENTER - BRIGHTNESS_USER_MULTIPLIER_MIN)
                + BRIGHTNESS_USER_MULTIPLIER_CENTER;
        }

        *AUTO_BRIGHTNESS_ADJUSTMENT.lock().await = adjustment;
        return adjustment;
    }

    async fn watch_auto_brightness_adjustment(
        &mut self,
        watch_adjustment_handler: Arc<Mutex<WatchHandler<f32, WatcherAdjustmentResponder>>>,
        responder: ControlWatchAutoBrightnessAdjustmentResponder,
    ) -> Result<(), Error> {
        let mut hanging_get_lock = watch_adjustment_handler.lock().await;
        hanging_get_lock
            .watch(WatcherAdjustmentResponder { watcher_adjustment_responder: responder })?;
        Ok(())
    }

    async fn get_max_absolute_brightness(&mut self) -> Result<f64, Error> {
        let backlight = self.backlight.lock().await;
        backlight.get_max_absolute_brightness().await
    }
}

#[async_trait(?Send)]
pub trait ControlTrait {
    async fn handle_request(
        &mut self,
        request: BrightnessControlRequest,
        watch_current_handler: Arc<Mutex<WatchHandler<f32, WatcherCurrentResponder>>>,
        watch_auto_handler: Arc<Mutex<WatchHandler<bool, WatcherAutoResponder>>>,
        watch_adjustment_handler: Arc<Mutex<WatchHandler<f32, WatcherAdjustmentResponder>>>,
    );
    async fn add_current_sender_channel(&mut self, sender: UnboundedSender<f32>);
    async fn add_auto_sender_channel(&mut self, sender: UnboundedSender<bool>);
    async fn add_adjustment_sender_channel(&mut self, sender: UnboundedSender<f32>);
    fn get_backlight_and_auto_brightness_on(&mut self) -> (Arc<Mutex<dyn BacklightControl>>, bool);
}

#[async_trait(?Send)]
impl ControlTrait for Control {
    async fn handle_request(
        &mut self,
        request: BrightnessControlRequest,
        watch_current_handler: Arc<Mutex<WatchHandler<f32, WatcherCurrentResponder>>>,
        watch_auto_handler: Arc<Mutex<WatchHandler<bool, WatcherAutoResponder>>>,
        watch_adjustment_handler: Arc<Mutex<WatchHandler<f32, WatcherAdjustmentResponder>>>,
    ) {
        self.handle_request(
            request,
            watch_current_handler,
            watch_auto_handler,
            watch_adjustment_handler,
        )
        .await;
    }

    async fn add_current_sender_channel(&mut self, sender: UnboundedSender<f32>) {
        self.add_current_sender_channel(sender).await;
    }

    async fn add_auto_sender_channel(&mut self, sender: UnboundedSender<bool>) {
        self.add_auto_sender_channel(sender).await;
    }

    async fn add_adjustment_sender_channel(&mut self, sender: UnboundedSender<f32>) {
        self.add_adjustment_sender_channel(sender).await;
    }

    fn get_backlight_and_auto_brightness_on(&mut self) -> (Arc<Mutex<dyn BacklightControl>>, bool) {
        self.get_backlight_and_auto_brightness_on()
    }
}

// TODO(kpt) Move all the folllowing functions into Control. This is delayed so that in the CL
// for the creation of this code the reviewer can see more easily that the code is unchanged
// after the extraction from main.rs.

fn read_brightness_table_file(path: &str) -> Result<BrightnessTable, Error> {
    let file = fs::File::open(path)?;
    let result = serde_json::from_reader(io::BufReader::new(file));
    let result = result
        .map_err(|e| anyhow::format_err!("Failed to read from file, ran into error: {:?}", e));
    result
}

fn generate_spline(table: &BrightnessTable) -> Spline<f32, f32> {
    let BrightnessTable { points } = table;
    let mut lux_to_nits_table_to_splines = Vec::new();
    for brightness_point in points {
        lux_to_nits_table_to_splines.push(Key::new(
            brightness_point.ambient_lux,
            brightness_point.display_nits,
            Interpolation::Linear,
        ));
    }
    Spline::from_iter(lux_to_nits_table_to_splines.iter().cloned())
}

// TODO(kpt) Move this and other functions into Control so that they can share the struct
/// Runs the main auto-brightness code.
/// This task monitors its running boolean and terminates if it goes false.

async fn get_current_brightness(backlight: Arc<Mutex<dyn BacklightControl>>) -> f32 {
    let backlight = backlight.lock().await;
    let fut = backlight.get_brightness();
    // TODO(lingxueluo) Deal with this in backlight.rs later.
    match fut.await {
        Ok(brightness) => brightness as f32,
        Err(e) => {
            if *GET_BRIGHTNESS_FAILED_FIRST.lock().await {
                fx_log_err!("Failed to get backlight: {}. assuming 1.0", e);
                *GET_BRIGHTNESS_FAILED_FIRST.lock().await = false;
            }
            *LAST_SET_BRIGHTNESS.lock().await
        }
    }
}

async fn read_sensor_and_get_brightness(
    sensor: Arc<Mutex<dyn SensorControl>>,
    spline: &Spline<f32, f32>,
    max_brightness: f64,
) -> f32 {
    let lux = {
        // Get the sensor reading in its own mutex block
        let sensor = sensor.lock().await;
        // TODO(kpt) Do we need a Mutex if sensor is only read?
        let fut = sensor.read();
        let report = fut.await.expect("Could not read from the sensor");
        report.illuminance
    };
    brightness_curve_lux_to_nits(lux, spline).await / max_brightness as f32
}

async fn brightness_curve_lux_to_nits(lux: u16, spline: &Spline<f32, f32>) -> f32 {
    let result = (*spline).clamped_sample(lux as f32);
    match result {
        Some(nits) => {
            return nits;
        }
        None => return 1.0,
    }
}

/// Sets the brightness of the backlight to a specific value.
/// An abortable task is spawned to handle this as it can take a while to do.
async fn set_brightness(
    value: f32,
    set_brightness_abort_handle: Arc<Mutex<Option<AbortHandle>>>,
    backlight: Arc<Mutex<dyn BacklightControl>>,
    current_sender_channel: Arc<Mutex<SenderChannel<f32>>>,
) {
    let value = num_traits::clamp(value, 0.0, 1.0);
    let current_value = get_current_brightness(backlight.clone()).await;
    if (current_value - value).abs() >= BRIGHTNESS_STEP_SIZE {
        let mut set_brightness_abort_handle = set_brightness_abort_handle.lock().await;
        if let Some(handle) = set_brightness_abort_handle.take() {
            handle.abort();
        }
        let (abort_handle, abort_registration) = AbortHandle::new_pair();
        let backlight = backlight.clone();
        let current_sender_channel = current_sender_channel.clone();
        fasync::Task::spawn(
            Abortable::new(
                async move {
                    set_brightness_impl(value, backlight, current_sender_channel).await;
                },
                abort_registration,
            )
            .unwrap_or_else(|_task_aborted| ()),
        )
        .detach();
        *set_brightness_abort_handle = Some(abort_handle);
    }
}

async fn set_brightness_impl(
    value: f32,
    backlight: Arc<Mutex<dyn BacklightControl>>,
    current_sender_channel: Arc<Mutex<SenderChannel<f32>>>,
) {
    let current_value = get_current_brightness(backlight.clone()).await;
    let mut backlight = backlight.lock().await;
    let set_brightness = |value| {
        backlight
            .set_brightness(value)
            .unwrap_or_else(|e| fx_log_err!("Failed to set backlight: {}", e))
    };
    let current_sender_channel = current_sender_channel.clone();
    set_brightness_slowly(
        current_value,
        value,
        set_brightness,
        *BRIGHTNESS_CHANGE_DURATION.lock().await,
        current_sender_channel,
    )
    .await;
}

/// Change the brightness of the screen slowly to `nits` nits. We don't want to change the screen
/// suddenly so we smooth the transition by doing it in a series of small steps.
/// The time per step can be changed if needed e.g. to fade up slowly and down quickly.
/// When testing we set time_per_step to zero.
async fn set_brightness_slowly(
    current_value: f32,
    to_value: f32,
    mut set_brightness: impl FnMut(f64),
    duration: Duration,
    current_sender_channel: Arc<Mutex<SenderChannel<f32>>>,
) {
    let mut current_value = current_value;
    let to_value = num_traits::clamp(to_value, 0.0, 1.0);
    assert!(to_value <= 1.0);
    assert!(current_value <= 1.0);
    let current_sender_channel = current_sender_channel.clone();
    let difference = to_value - current_value;
    let steps = (difference.abs() / BRIGHTNESS_STEP_SIZE) as u16;
    if steps > 0 {
        let time_per_step = cmp::min(duration / steps, MAX_BRIGHTNESS_STEP_TIME_MS.millis());
        let step_size = difference / steps as f32;
        for _i in 0..steps {
            let current_sender_channel = current_sender_channel.clone();
            current_value = current_value + step_size;
            set_brightness(current_value as f64);
            current_sender_channel.lock().await.send_value(current_value);
            if time_per_step.into_millis() > 0 {
                fuchsia_async::Timer::new(time_per_step.after_now()).await;
            }
        }
    }
    // Make sure we get to the correct value, there may be rounding errors
    set_brightness(to_value as f64);
    current_sender_channel.lock().await.send_value(current_value);
    *LAST_SET_BRIGHTNESS.lock().await = to_value;
}

#[cfg(test)]

mod tests {
    use super::*;

    use crate::sender_channel::SenderChannel;
    use crate::sensor::AmbientLightInputRpt;
    use anyhow::{format_err, Error};
    use async_trait::async_trait;
    use std::path::Path;

    struct MockSensor {
        illuminence: u16,
    }

    #[async_trait]
    impl SensorControl for MockSensor {
        async fn read(&self) -> Result<AmbientLightInputRpt, Error> {
            Ok(AmbientLightInputRpt {
                rpt_id: 0,
                state: 0,
                event: 0,
                illuminance: self.illuminence,
                red: 0,
                green: 0,
                blue: 0,
            })
        }
    }

    struct MockBacklight {
        valid_backlight: bool,
        value: f64,
        max_brightness: f64,
    }

    #[async_trait]
    impl BacklightControl for MockBacklight {
        async fn get_brightness(&self) -> Result<f64, Error> {
            if self.valid_backlight {
                Ok(self.value)
            } else {
                Err(format_err!("Get brightness failed."))
            }
        }

        fn set_brightness(&mut self, value: f64) -> Result<(), Error> {
            self.value = value;
            Ok(())
        }

        async fn get_max_absolute_brightness(&self) -> Result<f64, Error> {
            Ok(self.max_brightness)
        }
    }

    fn set_mocks(
        sensor: u16,
        backlight: f64,
    ) -> (Arc<Mutex<impl SensorControl>>, Arc<Mutex<impl BacklightControl>>) {
        let sensor = MockSensor { illuminence: sensor };
        let sensor = Arc::new(Mutex::new(sensor));
        let backlight =
            MockBacklight { valid_backlight: true, value: backlight, max_brightness: 250.0 };
        let backlight = Arc::new(Mutex::new(backlight));
        (sensor, backlight)
    }

    fn set_mocks_not_valid(
        sensor: u16,
        backlight: f64,
    ) -> (Arc<Mutex<impl SensorControl>>, Arc<Mutex<impl BacklightControl>>) {
        let sensor = MockSensor { illuminence: sensor };
        let sensor = Arc::new(Mutex::new(sensor));
        let backlight =
            MockBacklight { valid_backlight: false, value: backlight, max_brightness: 250.0 };
        let backlight = Arc::new(Mutex::new(backlight));
        (sensor, backlight)
    }

    async fn generate_control_struct() -> Control {
        let (sensor, backlight) = set_mocks(400, 0.5);
        let set_brightness_abort_handle = Arc::new(Mutex::new(None::<AbortHandle>));
        let auto_brightness_abort_handle = None::<AbortHandle>;
        let BrightnessTable { points } = &*BRIGHTNESS_TABLE.lock().await;
        let brightness_table_old = BrightnessTable { points: points.to_vec() };
        let spline_arg = generate_spline(brightness_table_old.clone());

        let current_sender_channel: SenderChannel<f32> = SenderChannel::new();
        let current_sender_channel = Arc::new(Mutex::new(current_sender_channel));

        let auto_sender_channel: SenderChannel<bool> = SenderChannel::new();
        let auto_sender_channel = Arc::new(Mutex::new(auto_sender_channel));

        let adjustment_sender_channel: SenderChannel<f32> = SenderChannel::new();
        let adjustment_sender_channel = Arc::new(Mutex::new(adjustment_sender_channel));
        Control {
            sensor,
            backlight,
            set_brightness_abort_handle,
            auto_brightness_abort_handle,
            spline: spline_arg,
            current_sender_channel,
            auto_sender_channel,
            adjustment_sender_channel,
        }
    }

    fn generate_spline(table: BrightnessTable) -> Spline<f32, f32> {
        let BrightnessTable { points } = &table;
        let mut lux_to_nits_table_to_splines = Vec::new();
        for brightness_point in points {
            lux_to_nits_table_to_splines.push(Key::new(
                brightness_point.ambient_lux,
                brightness_point.display_nits,
                Interpolation::Linear,
            ));
        }
        Spline::from_iter(lux_to_nits_table_to_splines.iter().cloned())
    }

    fn cmp_float(value1: f32, value2: f32) -> bool {
        (value1 - value2).abs() < 0.01
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_brightness_curve() {
        let BrightnessTable { points } = &*BRIGHTNESS_TABLE.lock().await;
        let brightness_table = BrightnessTable { points: points.to_vec() };
        let spline = generate_spline(brightness_table);

        assert_eq!(cmp_float(0., brightness_curve_lux_to_nits(0, &spline).await), true);
        assert_eq!(cmp_float(0.333, brightness_curve_lux_to_nits(1, &spline).await), true);
        assert_eq!(cmp_float(0.666, brightness_curve_lux_to_nits(2, &spline).await), true);
        assert_eq!(cmp_float(4.67, brightness_curve_lux_to_nits(15, &spline).await), true);
        assert_eq!(cmp_float(4.94, brightness_curve_lux_to_nits(16, &spline).await), true);
        assert_eq!(cmp_float(32.78, brightness_curve_lux_to_nits(100, &spline).await), true);
        assert_eq!(cmp_float(36.82, brightness_curve_lux_to_nits(150, &spline).await), true);
        assert_eq!(cmp_float(68.63, brightness_curve_lux_to_nits(200, &spline).await), true);
        assert_eq!(cmp_float(111.87, brightness_curve_lux_to_nits(240, &spline).await), true);
        assert_eq!(cmp_float(162.96, brightness_curve_lux_to_nits(300, &spline).await), true);
        assert_eq!(cmp_float(300., brightness_curve_lux_to_nits(340, &spline).await), true);
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_brightness_table_valid() {
        let mut control = generate_control_struct().await;
        let brightness_table = {
            let mut lux_to_nits = Vec::new();
            lux_to_nits.push(BrightnessPoint { ambient_lux: 10., display_nits: 50. });
            lux_to_nits.push(BrightnessPoint { ambient_lux: 30., display_nits: 50. });
            lux_to_nits.push(BrightnessPoint { ambient_lux: 60., display_nits: 50. });
            lux_to_nits.push(BrightnessPoint { ambient_lux: 100., display_nits: 50. });
            lux_to_nits.push(BrightnessPoint { ambient_lux: 150., display_nits: 50. });
            lux_to_nits.push(BrightnessPoint { ambient_lux: 210., display_nits: 50. });
            lux_to_nits.push(BrightnessPoint { ambient_lux: 250., display_nits: 50. });
            lux_to_nits.push(BrightnessPoint { ambient_lux: 300., display_nits: 50. });

            BrightnessTable { points: lux_to_nits }
        };
        control.check_brightness_table_and_set_new_curve(&brightness_table).await.unwrap();
        assert_eq!(cmp_float(50.0, brightness_curve_lux_to_nits(0, &control.spline).await), true);
        assert_eq!(cmp_float(50.0, brightness_curve_lux_to_nits(1, &control.spline).await), true);
        assert_eq!(cmp_float(50.0, brightness_curve_lux_to_nits(2, &control.spline).await), true);
        assert_eq!(cmp_float(50.0, brightness_curve_lux_to_nits(15, &control.spline).await), true);
        assert_eq!(cmp_float(50.0, brightness_curve_lux_to_nits(16, &control.spline).await), true);
        assert_eq!(cmp_float(50.0, brightness_curve_lux_to_nits(100, &control.spline).await), true);
        assert_eq!(cmp_float(50.0, brightness_curve_lux_to_nits(150, &control.spline).await), true);
        assert_eq!(cmp_float(50.0, brightness_curve_lux_to_nits(200, &control.spline).await), true);
        assert_eq!(cmp_float(50.0, brightness_curve_lux_to_nits(240, &control.spline).await), true);
        assert_eq!(cmp_float(50.0, brightness_curve_lux_to_nits(300, &control.spline).await), true);
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_brightness_table_not_valid_negative_value() {
        let mut control = generate_control_struct().await;
        let brightness_table = {
            let mut lux_to_nits = Vec::new();
            lux_to_nits.push(BrightnessPoint { ambient_lux: -10., display_nits: 50. });
            lux_to_nits.push(BrightnessPoint { ambient_lux: 30., display_nits: 50. });
            BrightnessTable { points: lux_to_nits }
        };
        control.check_brightness_table_and_set_new_curve(&brightness_table).await.unwrap_err();
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_brightness_table_not_valid_lux_not_increasing() {
        let mut control = generate_control_struct().await;
        let brightness_table = {
            let mut lux_to_nits = Vec::new();
            lux_to_nits.push(BrightnessPoint { ambient_lux: 10., display_nits: 50. });
            lux_to_nits.push(BrightnessPoint { ambient_lux: 30., display_nits: 50. });
            lux_to_nits.push(BrightnessPoint { ambient_lux: 3., display_nits: 50. });
            lux_to_nits.push(BrightnessPoint { ambient_lux: 100., display_nits: 50. });
            BrightnessTable { points: lux_to_nits }
        };
        control.check_brightness_table_and_set_new_curve(&brightness_table).await.unwrap_err();
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_brightness_table_valid_but_empty() {
        let mut control = generate_control_struct().await;
        let brightness_table = {
            let lux_to_nits = Vec::new();
            BrightnessTable { points: lux_to_nits }
        };
        let old_curve = &control.spline.clone();
        control.check_brightness_table_and_set_new_curve(&brightness_table).await.unwrap();
        assert_eq!(
            cmp_float(
                brightness_curve_lux_to_nits(0, old_curve).await,
                brightness_curve_lux_to_nits(0, &control.spline).await
            ),
            true
        );
        assert_eq!(
            cmp_float(
                brightness_curve_lux_to_nits(1, old_curve).await,
                brightness_curve_lux_to_nits(1, &control.spline).await
            ),
            true
        );
        assert_eq!(
            cmp_float(
                brightness_curve_lux_to_nits(2, old_curve).await,
                brightness_curve_lux_to_nits(2, &control.spline).await
            ),
            true
        );
        assert_eq!(
            cmp_float(
                brightness_curve_lux_to_nits(15, old_curve).await,
                brightness_curve_lux_to_nits(15, &control.spline).await
            ),
            true
        );
        assert_eq!(
            cmp_float(
                brightness_curve_lux_to_nits(16, old_curve).await,
                brightness_curve_lux_to_nits(16, &control.spline).await
            ),
            true
        );
        assert_eq!(
            cmp_float(
                brightness_curve_lux_to_nits(100, old_curve).await,
                brightness_curve_lux_to_nits(100, &control.spline).await
            ),
            true
        );
        assert_eq!(
            cmp_float(
                brightness_curve_lux_to_nits(150, old_curve).await,
                brightness_curve_lux_to_nits(150, &control.spline).await
            ),
            true
        );
        assert_eq!(
            cmp_float(
                brightness_curve_lux_to_nits(200, old_curve).await,
                brightness_curve_lux_to_nits(200, &control.spline).await
            ),
            true
        );
        assert_eq!(
            cmp_float(
                brightness_curve_lux_to_nits(240, old_curve).await,
                brightness_curve_lux_to_nits(240, &control.spline).await
            ),
            true
        );
        assert_eq!(
            cmp_float(
                brightness_curve_lux_to_nits(300, old_curve).await,
                brightness_curve_lux_to_nits(300, &control.spline).await
            ),
            true
        );
        assert_eq!(
            cmp_float(
                brightness_curve_lux_to_nits(340, old_curve).await,
                brightness_curve_lux_to_nits(340, &control.spline).await
            ),
            true
        );
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_scale_new_adjustment() {
        let mut control = generate_control_struct().await;
        let mut new_adjust = control.scale_new_adjustment(-1.0).await;
        assert_eq!(0.25, new_adjust);
        new_adjust = control.scale_new_adjustment(1.0).await;
        assert_eq!(8.0, new_adjust);
        new_adjust = control.scale_new_adjustment(0.0).await;
        assert_eq!(1.0, new_adjust);
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_set_brightness_slowly_send_value() {
        let control = generate_control_struct().await;
        let (channel_sender, mut channel_receiver) = futures::channel::mpsc::unbounded::<f32>();
        control.current_sender_channel.lock().await.add_sender_channel(channel_sender).await;
        let set_brightness = |_| {};
        set_brightness_slowly(0.4, 0.5, set_brightness, 0.millis(), control.current_sender_channel)
            .await;

        assert_eq!(cmp_float(0.4, channel_receiver.next().await.unwrap()), true);
        assert_eq!(cmp_float(0.4, channel_receiver.next().await.unwrap()), true);
        for _i in 0..13 {
            channel_receiver.next().await;
        }
        assert_eq!(cmp_float(0.41, channel_receiver.next().await.unwrap()), true);
        for _i in 0..4 {
            channel_receiver.next().await;
        }
        assert_eq!(cmp_float(0.42, channel_receiver.next().await.unwrap()), true);
        for _i in 0..19 {
            channel_receiver.next().await;
        }
        assert_eq!(cmp_float(0.44, channel_receiver.next().await.unwrap()), true);
        for _i in 0..58 {
            channel_receiver.next().await;
        }
        assert_eq!(cmp_float(0.50, channel_receiver.next().await.unwrap()), true);
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_set_brightness_slowly_in_range() {
        let control = generate_control_struct().await;
        let mut result = Vec::new();
        let set_brightness = |nits| {
            result.push(nits as f32);
        };
        set_brightness_slowly(0.4, 0.8, set_brightness, 0.millis(), control.current_sender_channel)
            .await;
        assert_eq!(401, result.len(), "wrong length");
        assert_eq!(cmp_float(0.4, result[0]), true);
        assert_eq!(cmp_float(0.4, result[1]), true);
        assert_eq!(cmp_float(0.41, result[15]), true);
        assert_eq!(cmp_float(0.42, result[20]), true);
        assert_eq!(cmp_float(0.44, result[40]), true);
        assert_eq!(cmp_float(0.50, result[100]), true);
        assert_eq!(cmp_float(0.55, result[150]), true);
        assert_eq!(cmp_float(0.60, result[200]), true);
        assert_eq!(cmp_float(0.65, result[250]), true);
        assert_eq!(cmp_float(0.70, result[300]), true);
        assert_eq!(cmp_float(0.75, result[350]), true);
        assert_eq!(cmp_float(0.80, result[399]), true);
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_set_brightness_slowly_min() {
        let control = generate_control_struct().await;
        let mut result = Vec::new();
        let set_brightness = |nits| {
            result.push(nits as f32);
        };
        set_brightness_slowly(0.4, 0.0, set_brightness, 0.millis(), control.current_sender_channel)
            .await;
        assert_eq!(401, result.len(), "wrong length");
        assert_eq!(cmp_float(0.39, result[0]), true);
        assert_eq!(cmp_float(0.39, result[1]), true);
        assert_eq!(cmp_float(0.38, result[15]), true);
        assert_eq!(cmp_float(0.38, result[20]), true);
        assert_eq!(cmp_float(0.35, result[40]), true);
        assert_eq!(cmp_float(0.30, result[100]), true);
        assert_eq!(cmp_float(0.25, result[150]), true);
        assert_eq!(cmp_float(0.20, result[200]), true);
        assert_eq!(cmp_float(0.15, result[250]), true);
        assert_eq!(cmp_float(0.10, result[300]), true);
        assert_eq!(cmp_float(0.05, result[350]), true);
        assert_eq!(cmp_float(0.00, result[399]), true);
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_set_brightness_slowly_max() {
        let control = generate_control_struct().await;
        let mut result = Vec::new();
        let set_brightness = |nits| {
            result.push(nits as f32);
        };
        set_brightness_slowly(0.9, 1.2, set_brightness, 0.millis(), control.current_sender_channel)
            .await;
        assert_eq!(101, result.len(), "wrong length");
        assert_eq!(cmp_float(0.90, result[0]), true);
        assert_eq!(cmp_float(0.90, result[1]), true);
        assert_eq!(cmp_float(0.91, result[10]), true);
        assert_eq!(cmp_float(0.92, result[20]), true);
        assert_eq!(cmp_float(0.93, result[30]), true);
        assert_eq!(cmp_float(0.94, result[40]), true);
        assert_eq!(cmp_float(0.95, result[50]), true);
        assert_eq!(cmp_float(0.96, result[60]), true);
        assert_eq!(cmp_float(0.97, result[70]), true);
        assert_eq!(cmp_float(0.98, result[80]), true);
        assert_eq!(cmp_float(0.99, result[90]), true);
        assert_eq!(cmp_float(1.00, result[100]), true);
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_read_sensor_and_get_brightness_bright() {
        let BrightnessTable { points } = &*BRIGHTNESS_TABLE.lock().await;
        let brightness_table = BrightnessTable { points: points.to_vec() };
        let spline = generate_spline(brightness_table);
        let (sensor, _backlight) = set_mocks(400, 1.5);
        let value = read_sensor_and_get_brightness(sensor, &spline, 250.0).await;
        assert_eq!(cmp_float(1.2, value), true);
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_read_sensor_and_get_brightness_low_light() {
        let BrightnessTable { points } = &*BRIGHTNESS_TABLE.lock().await;
        let brightness_table = BrightnessTable { points: points.to_vec() };
        let spline = generate_spline(brightness_table);
        let (sensor, _backlight) = set_mocks(0, 0.0);
        let value = read_sensor_and_get_brightness(sensor, &spline, 250.0).await;
        assert_eq!(cmp_float(0.0, value), true);
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_set_brightness_is_abortable_with_auto_brightness_on() {
        let control = generate_control_struct().await;
        let set_brightness_abort_handle = Arc::new(Mutex::new(None::<AbortHandle>));
        let (_sensor, backlight) = set_mocks(0, 0.0);
        let backlight = backlight.clone();
        set_brightness(
            0.04,
            set_brightness_abort_handle.clone(),
            backlight.clone(),
            control.current_sender_channel,
        )
        .await;
        // Abort the task before it really gets going
        let mut set_brightness_abort_handle = set_brightness_abort_handle.lock().await;
        if let Some(handle) = set_brightness_abort_handle.take() {
            handle.abort();
        }
        // It should not have reached the final value yet.
        // We know that set_brightness_slowly, at the bottom of the task, finishes at the correct
        // nits value from other tests if it has sufficient time.
        let backlight = backlight.lock().await;

        assert_ne!(cmp_float(0.04, backlight.get_brightness().await.unwrap() as f32), true);
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_set_brightness_impl() {
        let control = generate_control_struct().await;
        let (_sensor, backlight) = set_mocks(0, 0.0);
        let backlight_clone = backlight.clone();
        set_brightness_impl(0.3, backlight_clone, control.current_sender_channel).await;
        let backlight = backlight.lock().await;
        assert_eq!(cmp_float(0.3, backlight.get_brightness().await.unwrap() as f32), true);
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_brightness_manager_fail_gracefully() {
        let control = generate_control_struct().await;
        let (_sensor, backlight) = set_mocks_not_valid(0, 0.0);
        {
            let last_set_brightness = &*LAST_SET_BRIGHTNESS.lock().await;
            assert_eq!(cmp_float(*last_set_brightness, 1.0), true);
        }
        let backlight_clone = backlight.clone();
        set_brightness_impl(0.04, backlight_clone, control.current_sender_channel).await;
        let last_set_brightness = &*LAST_SET_BRIGHTNESS.lock().await;
        assert_eq!(cmp_float(*last_set_brightness, 0.04), true);
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_store_brightness_table() -> Result<(), Error> {
        let mut control = generate_control_struct().await;
        let brightness_table = BrightnessTable {
            points: vec![
                BrightnessPoint { ambient_lux: 10., display_nits: 50. },
                BrightnessPoint { ambient_lux: 30., display_nits: 50. },
                BrightnessPoint { ambient_lux: 60., display_nits: 50. },
            ],
        };
        control.store_brightness_table(&brightness_table, "/data/test_brightness_file")?;
        let file = fs::File::open("/data/test_brightness_file")?;
        let data = serde_json::from_reader(io::BufReader::new(file))?;
        let BrightnessTable { points: read_points } = data;
        let BrightnessTable { points: write_points } = brightness_table;
        let iter = read_points.iter().zip(write_points.iter());
        for point_tuple in iter {
            let (read_point, write_point) = point_tuple;
            assert_eq!(cmp_float(read_point.ambient_lux, write_point.ambient_lux), true);
            assert_eq!(cmp_float(read_point.display_nits, write_point.display_nits), true);
        }
        Ok(())
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_read_brightness_table_file_empty_file() {
        fs::File::create("/data/empty_file").unwrap();
        let result = read_brightness_table_file("/data/empty_file");
        assert_eq!(true, result.is_err());
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_read_brightness_table_file_missing_file() {
        assert_eq!(false, Path::new("/data/nonexistent_file").exists());
        let result = read_brightness_table_file("/data/nonexistent_file");
        assert_eq!(true, result.is_err());
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_read_brightness_table_file_invalid_data() {
        let file = fs::File::create("/data/invalid_brightness_file").unwrap();
        serde_json::to_writer(io::BufWriter::new(file), &1.0).unwrap();
        let result = read_brightness_table_file("/data/invalid_brightness_file");
        assert_eq!(true, result.is_err());
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_set_manual_brightness_smooth_with_duration_got_set() {
        let mut control = generate_control_struct().await;
        control.set_manual_brightness_smooth(0.6, 4000000000).await;
        let duration = *BRIGHTNESS_CHANGE_DURATION.lock().await;
        assert_eq!(4000, duration.into_millis());
    }

    #[test]
    fn test_set_manual_brightness_updates_brightness() {
        let mut exec = fasync::Executor::new().unwrap();

        let func_fut1 = generate_control_struct();
        futures::pin_mut!(func_fut1);
        let mut control = exec.run_singlethreaded(&mut func_fut1);
        {
            let func_fut2 = control.set_manual_brightness_smooth(0.6, 4000);
            futures::pin_mut!(func_fut2);
            exec.run_singlethreaded(&mut func_fut2);
        }
        let _ = exec.run_until_stalled(&mut future::pending::<()>());
        let func_fut3 = control.backlight.lock();
        futures::pin_mut!(func_fut3);
        let backlight = exec.run_singlethreaded(&mut func_fut3);
        let func_fut4 = backlight.get_brightness();
        futures::pin_mut!(func_fut4);
        let value = exec.run_singlethreaded(&mut func_fut4);
        assert_eq!(cmp_float(0.6, value.unwrap() as f32), true);
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_get_max_absolute_brightness() {
        let mut control = generate_control_struct().await;
        let max_brightness = control.get_max_absolute_brightness().await;
        assert_eq!(250.0, max_brightness.unwrap());
    }
}
