// 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::base::{SettingInfo, SettingType};
use crate::display::types::{LowLightMode, SetDisplayInfo, Theme, ThemeMode, ThemeType};
use crate::handler::base::Request;
use crate::ingress::{request, watch, Scoped};
use crate::job::source::{Error as JobError, ErrorResponder};
use crate::job::Job;
use fidl::endpoints::{ControlHandle, Responder};
use fidl_fuchsia_settings::{
    DisplayRequest, DisplaySetResponder, DisplaySetResult, DisplaySettings, DisplayWatchResponder,
    LowLightMode as FidlLowLightMode, Theme as FidlTheme, ThemeMode as FidlThemeMode,
    ThemeType as FidlThemeType,
};

impl From<FidlThemeMode> for ThemeMode {
    fn from(fidl: FidlThemeMode) -> Self {
        ThemeMode::from_bits(FidlThemeMode::bits(&fidl))
            .expect("failed to convert FidlThemeMode to ThemeMode")
    }
}

impl From<ThemeMode> for FidlThemeMode {
    fn from(fidl: ThemeMode) -> Self {
        FidlThemeMode::from_bits(ThemeMode::bits(&fidl))
            .expect("failed to convert ThemeMode to FidlThemeMode")
    }
}

impl From<FidlLowLightMode> for LowLightMode {
    fn from(fidl_low_light_mode: FidlLowLightMode) -> Self {
        match fidl_low_light_mode {
            FidlLowLightMode::Disable => LowLightMode::Disable,
            FidlLowLightMode::DisableImmediately => LowLightMode::DisableImmediately,
            FidlLowLightMode::Enable => LowLightMode::Enable,
        }
    }
}

impl From<FidlThemeType> for ThemeType {
    fn from(fidl_theme_type: FidlThemeType) -> Self {
        match fidl_theme_type {
            FidlThemeType::Default => ThemeType::Default,
            FidlThemeType::Light => ThemeType::Light,
            FidlThemeType::Dark => ThemeType::Dark,
        }
    }
}

impl From<FidlTheme> for Theme {
    fn from(fidl_theme: FidlTheme) -> Self {
        Self {
            theme_type: fidl_theme.theme_type.map(Into::into),
            theme_mode: fidl_theme.theme_mode.map(Into::into).unwrap_or_else(ThemeMode::empty),
        }
    }
}

impl From<SettingInfo> for DisplaySettings {
    fn from(response: SettingInfo) -> Self {
        if let SettingInfo::Brightness(info) = response {
            fidl_fuchsia_settings::DisplaySettings {
                auto_brightness: Some(info.auto_brightness),
                adjusted_auto_brightness: Some(info.auto_brightness_value),
                brightness_value: Some(info.manual_brightness_value),
                screen_enabled: Some(info.screen_enabled),
                low_light_mode: Some(match info.low_light_mode {
                    LowLightMode::Enable => FidlLowLightMode::Enable,
                    LowLightMode::Disable => FidlLowLightMode::Disable,
                    LowLightMode::DisableImmediately => FidlLowLightMode::DisableImmediately,
                }),
                theme: Some(FidlTheme {
                    theme_type: match info.theme {
                        Some(Theme { theme_type: Some(theme_type), .. }) => match theme_type {
                            ThemeType::Unknown => None,
                            ThemeType::Default => Some(FidlThemeType::Default),
                            ThemeType::Light => Some(FidlThemeType::Light),
                            ThemeType::Dark => Some(FidlThemeType::Dark),
                        },
                        _ => None,
                    },
                    theme_mode: match info.theme {
                        Some(Theme { theme_mode, .. }) if !theme_mode.is_empty() => {
                            Some(FidlThemeMode::from(theme_mode))
                        }
                        _ => None,
                    },
                    ..Default::default()
                }),
                ..Default::default()
            }
        } else {
            panic!("incorrect value sent to display");
        }
    }
}

impl ErrorResponder for DisplaySetResponder {
    fn id(&self) -> &'static str {
        "Display_Set"
    }

    fn respond(self: Box<Self>, error: fidl_fuchsia_settings::Error) -> Result<(), fidl::Error> {
        self.send(Err(error))
    }
}

impl request::Responder<Scoped<DisplaySetResult>> for DisplaySetResponder {
    fn respond(self, Scoped(response): Scoped<DisplaySetResult>) {
        let _ = self.send(response);
    }
}

impl watch::Responder<DisplaySettings, fuchsia_zircon::Status> for DisplayWatchResponder {
    fn respond(self, response: Result<DisplaySettings, fuchsia_zircon::Status>) {
        match response {
            Ok(settings) => {
                let _ = self.send(&settings);
            }
            Err(error) => {
                self.control_handle().shutdown_with_epitaph(error);
            }
        }
    }
}

fn to_request(settings: DisplaySettings) -> Option<Request> {
    let set_display_info = SetDisplayInfo {
        manual_brightness_value: settings.brightness_value,
        auto_brightness_value: settings.adjusted_auto_brightness,
        auto_brightness: settings.auto_brightness,
        screen_enabled: settings.screen_enabled,
        low_light_mode: settings.low_light_mode.map(Into::into),
        theme: settings.theme.map(Into::into),
    };
    match set_display_info {
        // No values being set is invalid
        SetDisplayInfo {
            manual_brightness_value: None,
            auto_brightness_value: None,
            auto_brightness: None,
            screen_enabled: None,
            low_light_mode: None,
            theme: None,
        } => None,
        _ => Some(Request::SetDisplayInfo(set_display_info)),
    }
}

impl TryFrom<DisplayRequest> for Job {
    type Error = JobError;
    fn try_from(req: DisplayRequest) -> Result<Self, Self::Error> {
        // Support future expansion of FIDL
        #[allow(unreachable_patterns)]
        match req {
            DisplayRequest::Set { settings, responder } => match to_request(settings) {
                Some(request) => {
                    Ok(request::Work::new(SettingType::Display, request, responder).into())
                }
                None => Err(JobError::InvalidInput(Box::new(responder))),
            },
            DisplayRequest::Watch { responder } => {
                Ok(watch::Work::new_job(SettingType::Display, responder))
            }
            _ => {
                tracing::warn!("Received a call to an unsupported API: {:?}", req);
                Err(JobError::Unsupported)
            }
        }
    }
}
