// 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 {
    anyhow::{Context as _, Error},
    fidl_fuchsia_settings::{ConfigurationInterfaces, LightState, LightValue, Theme},
    fuchsia_component::client::connect_to_service,
    structopt::StructOpt,
};

pub mod accessibility;
pub mod audio;
pub mod device;
pub mod display;
pub mod do_not_disturb;
pub mod factory_reset;
pub mod input;
pub mod intl;
pub mod light;
pub mod night_mode;
pub mod privacy;
pub mod setup;
pub mod utils;
pub mod volume_policy;

/// SettingClient exercises the functionality found in SetUI service. Currently,
/// action parameters are specified at as individual arguments, but the goal is
/// to eventually parse details from a JSON file input.
#[derive(StructOpt, Debug)]
#[structopt(name = "setui_client", about = "set setting values")]
pub enum SettingClient {
    // Operations that use the new interfaces.
    #[structopt(name = "accessibility")]
    Accessibility(AccessibilityOptions),

    #[structopt(name = "audio")]
    Audio {
        #[structopt(flatten)]
        streams: AudioStreams,

        #[structopt(flatten)]
        input: AudioInput,
    },

    // Operations that use the Device interface.
    #[structopt(name = "device")]
    Device { build_tag: Option<String> },

    #[structopt(name = "display")]
    Display {
        #[structopt(short = "b", long = "brightness")]
        brightness: Option<f32>,

        #[structopt(short = "o", long = "auto_brightness_level")]
        auto_brightness_level: Option<f32>,

        #[structopt(short = "a", long = "auto_brightness")]
        auto_brightness: Option<bool>,

        #[structopt(short = "l", long = "light_sensor")]
        light_sensor: bool,

        #[structopt(
            short = "m",
            long = "low_light_mode",
            parse(try_from_str = "str_to_low_light_mode")
        )]
        low_light_mode: Option<fidl_fuchsia_settings::LowLightMode>,

        #[structopt(short = "t", long = "theme", parse(try_from_str = "str_to_theme"))]
        theme: Option<fidl_fuchsia_settings::Theme>,

        #[structopt(short = "s", long = "screen_enabled")]
        screen_enabled: Option<bool>,
    },

    #[structopt(name = "do_not_disturb")]
    DoNotDisturb {
        #[structopt(short = "u", long = "user_dnd")]
        user_dnd: Option<bool>,

        #[structopt(short = "n", long = "night_mode_dnd")]
        night_mode_dnd: Option<bool>,
    },

    #[structopt(name = "factory_reset")]
    FactoryReset {
        #[structopt(short = "l", long = "is_local_reset_allowed")]
        is_local_reset_allowed: Option<bool>,
    },

    #[structopt(name = "input")]
    Input {
        #[structopt(short = "m", long = "mic_muted")]
        mic_muted: Option<bool>,
    },

    // TODO(fxbug.dev/65686): Move back into input when the clients are migrated over.
    // TODO(fxbug.dev/66186): Support multiple input devices to be set.
    // For simplicity, currently only supports setting one input device at a time.
    #[structopt(name = "input2")]
    Input2 {
        #[structopt(flatten)]
        input_device: InputDeviceOptions,
    },

    #[structopt(name = "intl")]
    Intl {
        #[structopt(short = "z", long, parse(from_str = "str_to_time_zone"))]
        time_zone: Option<fidl_fuchsia_intl::TimeZoneId>,

        #[structopt(short = "u", long, parse(try_from_str = "str_to_temperature_unit"))]
        // Valid options are Celsius and Fahrenheit, or just "c" and "f".
        temperature_unit: Option<fidl_fuchsia_intl::TemperatureUnit>,

        #[structopt(short, long, parse(from_str = "str_to_locale"))]
        /// List of locales, separated by spaces.
        locales: Vec<fidl_fuchsia_intl::LocaleId>,

        #[structopt(short = "h", long, parse(try_from_str = "str_to_hour_cycle"))]
        hour_cycle: Option<fidl_fuchsia_settings::HourCycle>,

        #[structopt(long)]
        /// If set, this flag will set locales as an empty list. Overrides the locales arguments.
        clear_locales: bool,
    },

    #[structopt(name = "light")]
    /// Reads and modifies the hardware light state. To get the value of all light types, omit all
    /// arguments. If setting the value for a light group, name is required, then only one type of
    /// value between simple, brightness, or rgb should be specified.
    Light {
        #[structopt(flatten)]
        light_group: LightGroup,
    },

    #[structopt(name = "night_mode")]
    NightMode {
        #[structopt(short, long)]
        night_mode_enabled: Option<bool>,
    },

    #[structopt(name = "privacy")]
    Privacy {
        #[structopt(short, long)]
        user_data_sharing_consent: Option<bool>,
    },

    #[structopt(name = "setup")]
    Setup {
        #[structopt(short = "i", long = "interfaces", parse(from_str = "str_to_interfaces"))]
        configuration_interfaces: Option<ConfigurationInterfaces>,
    },

    /// Reads and modifies volume policies that affect the behavior of the fuchsia.settings.audio.
    /// To list the policies, run the subcommand without any arguments.
    #[structopt(name = "volume_policy")]
    VolumePolicy {
        /// Adds a policy transform.
        #[structopt(subcommand)]
        add: Option<VolumePolicyCommands>,

        /// Removes a policy transform by its policy ID.
        #[structopt(short, long)]
        remove: Option<u32>,
    },
}

#[derive(StructOpt, Debug, Clone, Copy, Default)]
pub struct AccessibilityOptions {
    #[structopt(short = "a", long)]
    pub audio_description: Option<bool>,

    #[structopt(short = "s", long)]
    pub screen_reader: Option<bool>,

    #[structopt(short = "i", long)]
    pub color_inversion: Option<bool>,

    #[structopt(short = "m", long)]
    pub enable_magnification: Option<bool>,

    #[structopt(short = "c", long, parse(try_from_str = "str_to_color_blindness_type"))]
    pub color_correction: Option<fidl_fuchsia_settings::ColorBlindnessType>,

    #[structopt(subcommand)]
    pub caption_options: Option<CaptionCommands>,
}

#[derive(StructOpt, Debug, Clone, Copy)]
pub enum CaptionCommands {
    #[structopt(name = "captions")]
    CaptionOptions(CaptionOptions),
}

#[derive(StructOpt, Debug, Clone, Copy)]
pub struct CaptionOptions {
    #[structopt(short = "m", long)]
    /// Enable closed captions for media sources of audio.
    pub for_media: Option<bool>,

    #[structopt(short = "t", long)]
    /// Enable closed captions for Text-To-Speech sources of audio.
    pub for_tts: Option<bool>,

    #[structopt(short, long, parse(try_from_str = "str_to_color"))]
    /// Border color used around the closed captions window. Valid options are red, green, or blue,
    /// or just the first letter of each color (r, g, b).
    pub window_color: Option<fidl_fuchsia_ui_types::ColorRgba>,

    #[structopt(short, long, parse(try_from_str = "str_to_color"))]
    /// Border color used around the closed captions window. Valid options are red, green, or blue,
    /// or just the first letter of each color (r, g, b).
    pub background_color: Option<fidl_fuchsia_ui_types::ColorRgba>,

    #[structopt(flatten)]
    pub style: CaptionFontStyle,
}

#[derive(StructOpt, Debug, Clone, Copy)]
pub enum VolumePolicyCommands {
    #[structopt(name = "add")]
    AddPolicy(VolumePolicyOptions),
}

#[derive(StructOpt, Debug, Clone, Copy)]
pub struct VolumePolicyOptions {
    /// Target to apply the policy transform to.
    #[structopt(parse(try_from_str = "str_to_audio_stream"))]
    pub target: fidl_fuchsia_media::AudioRenderUsage,

    #[structopt(long)]
    pub min: Option<f32>,

    #[structopt(long)]
    pub max: Option<f32>,
}

#[derive(StructOpt, Debug, Clone, Copy)]
pub struct CaptionFontStyle {
    #[structopt(short, long, parse(try_from_str = "str_to_font_family"))]
    /// Font family for captions, specified by 47 CFR §79.102(k). Valid options are unknown,
    /// monospaced_serif, proportional_serif, monospaced_sans_serif, proportional_sans_serif,
    /// casual, cursive, and small_capitals,
    pub font_family: Option<fidl_fuchsia_settings::CaptionFontFamily>,

    #[structopt(short = "c", long, parse(try_from_str = "str_to_color"))]
    /// Color of the closed cpation text. Valid options are red, green, or blue, or just the first
    /// letter of each color (r, g, b).
    pub font_color: Option<fidl_fuchsia_ui_types::ColorRgba>,

    #[structopt(short, long)]
    /// Size of closed captions text relative to the default captions size. A range of [0.5, 2] is
    /// guaranteed to be supported (as 47 CFR §79.103(c)(4) establishes).
    pub relative_size: Option<f32>,

    #[structopt(short = "e", long, parse(try_from_str = "str_to_edge_style"))]
    /// Edge style for fonts as specified in 47 CFR §79.103(c)(7), valid options are none,
    /// drop_shadow, raised, depressed, and outline.
    pub char_edge_style: Option<fidl_fuchsia_settings::EdgeStyle>,
}

#[derive(StructOpt, Debug, Clone)]
pub struct InputDeviceOptions {
    #[structopt(short = "t", long = "type", parse(try_from_str = "str_to_device_type"))]
    /// The type of input device, e.g. camera or microphone.
    device_type: Option<fidl_fuchsia_settings::DeviceType>,

    #[structopt(short = "n", long = "name")]
    /// The name of the device. Must be unique within a device type.
    device_name: Option<String>,

    #[structopt(short = "s", long = "state", parse(try_from_str = "str_to_device_state"))]
    /// The device state flags, represented by the integer value of the bitwise flags.
    ///
    /// Available = 1
    /// Active = 2
    /// Muted = 4
    /// Disabled = 8
    /// Error = 16
    ///
    /// For combinations of states, add these values together.
    /// Ex: Available && Active -> 1 + 2 -> 3
    device_state: Option<fidl_fuchsia_settings::DeviceState>,
}

#[derive(StructOpt, Debug)]
pub struct AudioStreams {
    #[structopt(short = "t", long = "stream", parse(try_from_str = "str_to_audio_stream"))]
    stream: Option<fidl_fuchsia_media::AudioRenderUsage>,
    #[structopt(short = "s", long = "source", parse(try_from_str = "str_to_audio_source"))]
    source: Option<fidl_fuchsia_settings::AudioStreamSettingSource>,
    #[structopt(flatten)]
    user_volume: UserVolume,
}

#[derive(StructOpt, Debug)]
struct UserVolume {
    #[structopt(short = "l", long = "level")]
    level: Option<f32>,

    #[structopt(short = "v", long = "volume_muted")]
    volume_muted: Option<bool>,
}

#[derive(StructOpt, Debug)]
pub struct AudioInput {
    #[structopt(short = "m", long = "input_muted")]
    input_muted: Option<bool>,
}

#[derive(StructOpt, Debug, Clone)]
pub struct LightGroup {
    #[structopt(short, long)]
    /// Name of a light group to set values for. Required if setting the value of a light group.
    pub name: Option<String>,

    #[structopt(short, long)]
    /// Repeated parameter for a list of simple on/off values to set for a light group.
    pub simple: Vec<bool>,

    #[structopt(short, long)]
    /// Repeated parameter for a list of floating point brightness values from 0.0-1.0 inclusive
    /// to set for a light group, where 0.0 is minimum brightness and 1.0 is maximum.
    pub brightness: Vec<f64>,

    #[structopt(short, long, parse(try_from_str = "str_to_rgb"))]
    /// Repeated parameter for a list of RGB values to set for a light group. Values should be in
    /// the range of 0.0-1.0 inclusive and should be specified as a comma-separated list of the red,
    /// green, and blue components. Ex. 0.1,0.4,0.23
    pub rgb: Vec<fidl_fuchsia_ui_types::ColorRgb>,
}

impl Into<Vec<LightState>> for LightGroup {
    fn into(self) -> Vec<LightState> {
        if self.simple.len() > 0 {
            return self
                .simple
                .clone()
                .into_iter()
                .map(|val| LightState { value: Some(LightValue::On(val)), ..LightState::EMPTY })
                .collect::<Vec<_>>();
        }

        if self.brightness.len() > 0 {
            return self
                .brightness
                .clone()
                .into_iter()
                .map(|val| LightState {
                    value: Some(LightValue::Brightness(val)),
                    ..LightState::EMPTY
                })
                .collect::<Vec<_>>();
        }

        if self.rgb.len() > 0 {
            return self
                .rgb
                .clone()
                .into_iter()
                .map(|val| LightState { value: Some(LightValue::Color(val)), ..LightState::EMPTY })
                .collect::<Vec<_>>();
        }

        return Vec::new();
    }
}

pub async fn run_command(command: SettingClient) -> Result<(), Error> {
    match command {
        SettingClient::Device { build_tag } => {
            if let Some(_build_tag_val) = build_tag {
                panic!("Cannot set device settings");
            }
            let device_service = connect_to_service::<fidl_fuchsia_settings::DeviceMarker>()
                .context("Failed to connect to device service")?;
            utils::print_results("Device", device::command(device_service)).await?;
        }
        SettingClient::Display {
            brightness,
            auto_brightness_level,
            auto_brightness,
            light_sensor,
            low_light_mode,
            theme,
            screen_enabled,
        } => {
            let display_service = connect_to_service::<fidl_fuchsia_settings::DisplayMarker>()
                .context("Failed to connect to display service")?;
            utils::handle_mixed_result(
                "Display",
                display::command(
                    display_service,
                    brightness,
                    auto_brightness,
                    auto_brightness_level,
                    light_sensor,
                    low_light_mode,
                    theme,
                    screen_enabled,
                )
                .await,
            )
            .await?;
        }
        SettingClient::DoNotDisturb { user_dnd, night_mode_dnd } => {
            let dnd_service = connect_to_service::<fidl_fuchsia_settings::DoNotDisturbMarker>()
                .context("Failed to connect to do_not_disturb service")?;
            utils::handle_mixed_result(
                "DoNoDisturb",
                do_not_disturb::command(dnd_service, user_dnd, night_mode_dnd).await,
            )
            .await?;
        }
        SettingClient::FactoryReset { is_local_reset_allowed } => {
            let factory_reset_service =
                connect_to_service::<fidl_fuchsia_settings::FactoryResetMarker>()
                    .context("Failed to connect to factory_reset service")?;
            utils::handle_mixed_result(
                "FactoryReset",
                factory_reset::command(factory_reset_service, is_local_reset_allowed).await,
            )
            .await?;
        }
        SettingClient::Intl { time_zone, temperature_unit, locales, hour_cycle, clear_locales } => {
            let intl_service = connect_to_service::<fidl_fuchsia_settings::IntlMarker>()
                .context("Failed to connect to intl service")?;
            utils::handle_mixed_result(
                "Intl",
                intl::command(
                    intl_service,
                    time_zone,
                    temperature_unit,
                    locales,
                    hour_cycle,
                    clear_locales,
                )
                .await,
            )
            .await?;
        }
        SettingClient::Light { light_group } => {
            let light_mode_service = connect_to_service::<fidl_fuchsia_settings::LightMarker>()
                .context("Failed to connect to light service")?;
            utils::handle_mixed_result(
                "Light",
                light::command(light_mode_service, light_group).await,
            )
            .await?;
        }
        SettingClient::NightMode { night_mode_enabled } => {
            let night_mode_service = connect_to_service::<fidl_fuchsia_settings::NightModeMarker>()
                .context("Failed to connect to night mode service")?;
            utils::handle_mixed_result(
                "NightMode",
                night_mode::command(night_mode_service, night_mode_enabled).await,
            )
            .await?;
        }
        SettingClient::Accessibility(accessibility_options) => {
            let accessibility_service =
                connect_to_service::<fidl_fuchsia_settings::AccessibilityMarker>()
                    .context("Failed to connect to accessibility service")?;

            utils::handle_mixed_result(
                "Accessibility",
                accessibility::command(accessibility_service, accessibility_options).await,
            )
            .await?;
        }
        SettingClient::Privacy { user_data_sharing_consent } => {
            let privacy_service = connect_to_service::<fidl_fuchsia_settings::PrivacyMarker>()
                .context("Failed to connect to privacy service")?;
            utils::handle_mixed_result(
                "Privacy",
                privacy::command(privacy_service, user_data_sharing_consent).await,
            )
            .await?;
        }
        SettingClient::Audio { streams, input } => {
            let audio_service = connect_to_service::<fidl_fuchsia_settings::AudioMarker>()
                .context("Failed to connect to audio service")?;
            let stream = streams.stream;
            let source = streams.source;
            let level = streams.user_volume.level;
            let volume_muted = streams.user_volume.volume_muted;
            let input_muted = input.input_muted;
            utils::handle_mixed_result(
                "Audio",
                audio::command(audio_service, stream, source, level, volume_muted, input_muted)
                    .await,
            )
            .await?;
        }
        SettingClient::Input { mic_muted } => {
            let input_service = connect_to_service::<fidl_fuchsia_settings::InputMarker>()
                .context("Failed to connect to input service")?;
            utils::handle_mixed_result("Input", input::command(input_service, mic_muted).await)
                .await?;
        }
        SettingClient::Input2 { input_device } => {
            let input_service = connect_to_service::<fidl_fuchsia_settings::InputMarker>()
                .context("Failed to connect to input2 service")?;
            let device_type = input_device.device_type;
            let device_name = input_device.device_name;
            let device_state = input_device.device_state;
            utils::handle_mixed_result(
                "Input2",
                input::command2(input_service, device_type, device_name, device_state).await,
            )
            .await?;
        }
        SettingClient::Setup { configuration_interfaces } => {
            let setup_service = connect_to_service::<fidl_fuchsia_settings::SetupMarker>()
                .context("Failed to connect to setup service")?;
            utils::handle_mixed_result(
                "Setup",
                setup::command(setup_service, configuration_interfaces).await,
            )
            .await?;
        }
        SettingClient::VolumePolicy { add, remove } => {
            let setup_service =
                connect_to_service::<fidl_fuchsia_settings_policy::VolumePolicyControllerMarker>()
                    .context("Failed to connect to volume policy service")?;
            utils::handle_mixed_result(
                "Volume policy",
                volume_policy::command(setup_service, add, remove).await,
            )
            .await?;
        }
    }
    Ok(())
}

fn str_to_time_zone(src: &&str) -> fidl_fuchsia_intl::TimeZoneId {
    fidl_fuchsia_intl::TimeZoneId { id: src.to_string() }
}

fn str_to_locale(src: &str) -> fidl_fuchsia_intl::LocaleId {
    fidl_fuchsia_intl::LocaleId { id: src.to_string() }
}

fn str_to_device_type(src: &str) -> Result<fidl_fuchsia_settings::DeviceType, &str> {
    let device_type = src.to_lowercase();
    if device_type.contains("microphone") {
        Ok(fidl_fuchsia_settings::DeviceType::Microphone)
    } else if device_type.contains("camera") {
        Ok(fidl_fuchsia_settings::DeviceType::Camera)
    } else {
        Err("Unidentified device type")
    }
}

fn str_to_device_state(src: &str) -> Result<fidl_fuchsia_settings::DeviceState, &str> {
    let bits = src.parse::<u64>().map_err(|_| "Failed to parse device state")?;
    let mut device_state = fidl_fuchsia_settings::DeviceState::EMPTY;
    device_state.toggle_flags = fidl_fuchsia_settings::ToggleStateFlags::from_bits(bits);
    Ok(device_state)
}

fn str_to_low_light_mode(src: &str) -> Result<fidl_fuchsia_settings::LowLightMode, &str> {
    if src.contains("enable") {
        Ok(fidl_fuchsia_settings::LowLightMode::Enable)
    } else if src.contains("disable") {
        Ok(fidl_fuchsia_settings::LowLightMode::Disable)
    } else if src.contains("disableimmediately") {
        Ok(fidl_fuchsia_settings::LowLightMode::DisableImmediately)
    } else {
        Err("Couldn't parse low light mode")
    }
}

fn str_to_theme(src: &str) -> Result<fidl_fuchsia_settings::Theme, &str> {
    match src {
        "default" => Ok(Theme {
            theme_type: Some(fidl_fuchsia_settings::ThemeType::Default),
            ..Theme::EMPTY
        }),
        "dark" => {
            Ok(Theme { theme_type: Some(fidl_fuchsia_settings::ThemeType::Dark), ..Theme::EMPTY })
        }
        "light" => {
            Ok(Theme { theme_type: Some(fidl_fuchsia_settings::ThemeType::Light), ..Theme::EMPTY })
        }
        "auto" => {
            Ok(Theme { theme_type: Some(fidl_fuchsia_settings::ThemeType::Auto), ..Theme::EMPTY })
        }
        _ => Err("Couldn't parse theme."),
    }
}

fn str_to_interfaces(src: &&str) -> ConfigurationInterfaces {
    let mut interfaces = ConfigurationInterfaces::empty();

    for interface in src.split(",") {
        match interface.to_lowercase().as_str() {
            "eth" | "ethernet" => {
                interfaces = interfaces | ConfigurationInterfaces::Ethernet;
            }
            "wireless" | "wifi" => {
                interfaces = interfaces | ConfigurationInterfaces::Wifi;
            }
            _ => {}
        }
    }

    return interfaces;
}

fn str_to_color(src: &str) -> Result<fidl_fuchsia_ui_types::ColorRgba, &str> {
    Ok(match src.to_lowercase().as_str() {
        "red" | "r" => {
            fidl_fuchsia_ui_types::ColorRgba { red: 255.0, green: 0.0, blue: 0.0, alpha: 255.0 }
        }
        "green" | "g" => {
            fidl_fuchsia_ui_types::ColorRgba { red: 0.0, green: 2.055, blue: 0.0, alpha: 255.0 }
        }
        "blue" | "b" => {
            fidl_fuchsia_ui_types::ColorRgba { red: 0.0, green: 0.0, blue: 255.0, alpha: 255.0 }
        }
        _ => return Err("Couldn't parse color"),
    })
}

/// Converts a comma-separated string of RGB values into a fidl_fuchsia_ui_types::ColorRgb.
fn str_to_rgb(src: &str) -> Result<fidl_fuchsia_ui_types::ColorRgb, &str> {
    let mut part_iter =
        src.split(',').map(|p| p.parse::<f32>().map_err(|_| "failed to parse color value"));

    const WRONG_COUNT: &str = "wrong number of values";
    let color = fidl_fuchsia_ui_types::ColorRgb {
        red: part_iter.next().unwrap_or_else(|| Err(WRONG_COUNT))?,
        green: part_iter.next().unwrap_or_else(|| Err(WRONG_COUNT))?,
        blue: part_iter.next().unwrap_or_else(|| Err(WRONG_COUNT))?,
    };
    part_iter.next().map(|_| Err(WRONG_COUNT)).unwrap_or(Ok(color))
}

fn str_to_font_family(src: &str) -> Result<fidl_fuchsia_settings::CaptionFontFamily, &str> {
    Ok(match src.to_lowercase().as_str() {
        "unknown" => fidl_fuchsia_settings::CaptionFontFamily::Unknown,
        "monospaced_serif" => fidl_fuchsia_settings::CaptionFontFamily::MonospacedSerif,
        "proportional_serif" => fidl_fuchsia_settings::CaptionFontFamily::ProportionalSerif,
        "monospaced_sans_serif" => fidl_fuchsia_settings::CaptionFontFamily::MonospacedSansSerif,
        "proportional_sans_serif" => {
            fidl_fuchsia_settings::CaptionFontFamily::ProportionalSansSerif
        }
        "casual" => fidl_fuchsia_settings::CaptionFontFamily::Casual,
        "cursive" => fidl_fuchsia_settings::CaptionFontFamily::Cursive,
        "small_capitals" => fidl_fuchsia_settings::CaptionFontFamily::SmallCapitals,
        _ => return Err("Couldn't parse font family"),
    })
}

fn str_to_edge_style(src: &str) -> Result<fidl_fuchsia_settings::EdgeStyle, &str> {
    Ok(match src.to_lowercase().as_str() {
        "none" => fidl_fuchsia_settings::EdgeStyle::None,
        "drop_shadow" => fidl_fuchsia_settings::EdgeStyle::DropShadow,
        "raised" => fidl_fuchsia_settings::EdgeStyle::Raised,
        "depressed" => fidl_fuchsia_settings::EdgeStyle::Depressed,
        "outline" => fidl_fuchsia_settings::EdgeStyle::Outline,
        _ => return Err("Couldn't parse edge style"),
    })
}

fn str_to_temperature_unit(src: &str) -> Result<fidl_fuchsia_intl::TemperatureUnit, &str> {
    match src.to_lowercase().as_str() {
        "c" | "celsius" => Ok(fidl_fuchsia_intl::TemperatureUnit::Celsius),
        "f" | "fahrenheit" => Ok(fidl_fuchsia_intl::TemperatureUnit::Fahrenheit),
        _ => Err("Couldn't parse temperature"),
    }
}

fn str_to_hour_cycle(src: &str) -> Result<fidl_fuchsia_settings::HourCycle, &str> {
    match src.to_lowercase().as_str() {
        "unknown" => Ok(fidl_fuchsia_settings::HourCycle::Unknown),
        "h11" => Ok(fidl_fuchsia_settings::HourCycle::H11),
        "h12" => Ok(fidl_fuchsia_settings::HourCycle::H12),
        "h23" => Ok(fidl_fuchsia_settings::HourCycle::H23),
        "h24" => Ok(fidl_fuchsia_settings::HourCycle::H24),
        _ => Err("Couldn't parse hour cycle"),
    }
}

fn str_to_color_blindness_type(
    src: &str,
) -> Result<fidl_fuchsia_settings::ColorBlindnessType, &str> {
    match src.to_lowercase().as_str() {
        "none" | "n" => Ok(fidl_fuchsia_settings::ColorBlindnessType::None),
        "protanomaly" | "p" => Ok(fidl_fuchsia_settings::ColorBlindnessType::Protanomaly),
        "deuteranomaly" | "d" => Ok(fidl_fuchsia_settings::ColorBlindnessType::Deuteranomaly),
        "tritanomaly" | "t" => Ok(fidl_fuchsia_settings::ColorBlindnessType::Tritanomaly),
        _ => Err("Couldn't parse color blindness type"),
    }
}

fn str_to_audio_stream(src: &str) -> Result<fidl_fuchsia_media::AudioRenderUsage, &str> {
    match src.to_lowercase().as_str() {
        "background" | "b" => Ok(fidl_fuchsia_media::AudioRenderUsage::Background),
        "media" | "m" => Ok(fidl_fuchsia_media::AudioRenderUsage::Media),
        "interruption" | "i" => Ok(fidl_fuchsia_media::AudioRenderUsage::Interruption),
        "system_agent" | "systemagent" | "system agent" | "s" => {
            Ok(fidl_fuchsia_media::AudioRenderUsage::SystemAgent)
        }
        "communication" | "c" => Ok(fidl_fuchsia_media::AudioRenderUsage::Communication),
        _ => Err("Couldn't parse audio stream type"),
    }
}

fn str_to_audio_source(src: &str) -> Result<fidl_fuchsia_settings::AudioStreamSettingSource, &str> {
    match src.to_lowercase().as_str() {
        "user" | "u" => Ok(fidl_fuchsia_settings::AudioStreamSettingSource::User),
        "system" | "s" => Ok(fidl_fuchsia_settings::AudioStreamSettingSource::System),
        _ => Err("Couldn't parse audio source type"),
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    /// Unit test for str_to_audio_stream.
    #[test]
    fn test_str_to_audio_stream() {
        println!("Running test_str_to_audio_stream");
        let test_cases = vec![
            "Background",
            "MEDIA",
            "interruption",
            "SYSTEM_AGENT",
            "SystemAgent",
            "system agent",
            "Communication",
            "unexpected_stream_type",
        ];
        let expected = vec![
            Ok(fidl_fuchsia_media::AudioRenderUsage::Background),
            Ok(fidl_fuchsia_media::AudioRenderUsage::Media),
            Ok(fidl_fuchsia_media::AudioRenderUsage::Interruption),
            Ok(fidl_fuchsia_media::AudioRenderUsage::SystemAgent),
            Ok(fidl_fuchsia_media::AudioRenderUsage::SystemAgent),
            Ok(fidl_fuchsia_media::AudioRenderUsage::SystemAgent),
            Ok(fidl_fuchsia_media::AudioRenderUsage::Communication),
            Err("Couldn't parse audio stream type"),
        ];
        let mut results = vec![];
        for test_case in test_cases {
            results.push(str_to_audio_stream(test_case));
        }
        for (expected, result) in expected.iter().zip(results.iter()) {
            assert_eq!(expected, result);
        }
    }

    /// Unit test for str_to_audio_source.
    #[test]
    fn test_str_to_audio_source() {
        println!("Running test_str_to_audio_source");
        let test_cases = vec!["USER", "system", "unexpected_source_type"];
        let expected = vec![
            Ok(fidl_fuchsia_settings::AudioStreamSettingSource::User),
            Ok(fidl_fuchsia_settings::AudioStreamSettingSource::System),
            Err("Couldn't parse audio source type"),
        ];
        let mut results = vec![];
        for test_case in test_cases {
            results.push(str_to_audio_source(test_case));
        }
        for (expected, result) in expected.iter().zip(results.iter()) {
            assert_eq!(expected, result);
        }
    }
}
