// 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.

#[cfg(test)]
use std::collections::HashMap;
use std::option::Option::Some;
use std::sync::Arc;

use fidl_fuchsia_settings::{LightError, LightMarker, LightProxy};
use futures::lock::Mutex;

use crate::agent::restore_agent;
use crate::registry::device_storage::testing::*;
use crate::registry::device_storage::DeviceStorage;
use crate::switchboard::base::SettingType;
use crate::switchboard::light_types::{
    ColorRgb, LightGroup, LightInfo, LightState, LightType, LightValue,
};
use crate::tests::fakes::hardware_light_service::HardwareLightService;
use crate::tests::fakes::service_registry::ServiceRegistry;
use crate::EnvironmentBuilder;

type HardwareLightServiceHandle = Arc<Mutex<HardwareLightService>>;

const ENV_NAME: &str = "settings_service_light_test_environment";
const CONTEXT_ID: u64 = 0;

const LIGHT_NAME_1: &str = "light_name_1";
const LIGHT_NAME_2: &str = "light_name_2";

fn get_test_light_info() -> LightInfo {
    let mut light_groups = HashMap::new();
    light_groups.insert(
        LIGHT_NAME_1.to_string(),
        LightGroup {
            name: LIGHT_NAME_1.to_string(),
            enabled: true,
            light_type: LightType::Brightness,
            lights: vec![LightState { value: Some(LightValue::Brightness(42)) }],
            hardware_index: vec![0],
        },
    );
    light_groups.insert(
        LIGHT_NAME_2.to_string(),
        LightGroup {
            name: LIGHT_NAME_2.to_string(),
            enabled: true,
            light_type: LightType::Simple,
            lights: vec![LightState { value: Some(LightValue::Simple(true)) }],
            hardware_index: vec![1],
        },
    );

    LightInfo { light_groups }
}

/// Populates the given HardwareLightService fake with the lights from a LightInfo.
///
/// Assumes that each light group has one light, as if the light groups were read from the
/// underlying fuchsia.hardware.light API.
async fn populate_single_test_lights(
    hardware_light_service_handle: HardwareLightServiceHandle,
    light_info: LightInfo,
) {
    for (name, group) in light_info.light_groups.into_iter() {
        hardware_light_service_handle
            .lock()
            .await
            .insert_light(
                group.hardware_index[0],
                name,
                group.light_type,
                group.lights[0].value.clone().unwrap(),
            )
            .await;
    }
}

/// Populates the given HardwareLightService fake with the lights from a LightInfo.
///
/// For each light group, adds a new light with the light's index in the LightGroup appended to it.
/// For example a light group with name RED and 3 lights would result in RED_1, RED_2, RED_3 being
/// inserted into the fake service.
async fn populate_multiple_test_lights(
    hardware_light_service_handle: HardwareLightServiceHandle,
    light_info: LightInfo,
) {
    for (name, group) in light_info.light_groups.into_iter() {
        for i in 0..group.hardware_index.len() {
            hardware_light_service_handle
                .lock()
                .await
                .insert_light(
                    group.hardware_index[i],
                    format!("{}_{}", name, i),
                    group.light_type.clone(),
                    group.lights[i].value.clone().unwrap(),
                )
                .await;
        }
    }
}

/// Creates a test environment for light.
///
/// If starting_light_info is provided, the device storage will be initialized with the given value.
/// If hardware_light_service_handle is provided, it will be used as the fake service in the service
/// registry, otherwise one will be constructed.
async fn create_test_light_env_with_service(
    starting_light_info: Option<LightInfo>,
    hardware_light_service_handle: Option<HardwareLightServiceHandle>,
) -> (LightProxy, Arc<Mutex<DeviceStorage<LightInfo>>>) {
    let service_registry = ServiceRegistry::create();
    let service_handle = match hardware_light_service_handle.clone() {
        Some(service) => service,
        None => Arc::new(Mutex::new(HardwareLightService::new())),
    };
    service_registry.lock().await.register_service(service_handle.clone());

    let storage_factory = InMemoryStorageFactory::create();
    let store = storage_factory
        .lock()
        .await
        .get_device_storage::<LightInfo>(StorageAccessContext::Test, CONTEXT_ID);

    if let Some(info) = starting_light_info {
        store.lock().await.write(&info, false).await.expect("write starting values");
        if hardware_light_service_handle.is_none() {
            // If a fake hardware light service wasn't provided for us, populate the initial lights.
            populate_single_test_lights(service_handle.clone(), info).await;
        }
    }

    let env = EnvironmentBuilder::new(storage_factory)
        .service(Box::new(ServiceRegistry::serve(service_registry)))
        .agents(&[restore_agent::blueprint::create()])
        .settings(&[SettingType::Light])
        .spawn_and_get_nested_environment(ENV_NAME)
        .await
        .unwrap();

    let light_service = env.connect_to_service::<LightMarker>().unwrap();

    (light_service, store)
}

async fn set_light_value(service: &LightProxy, light_group: LightGroup) {
    service
        .set_light_group_values(
            light_group.name.as_str(),
            &mut light_group.lights.into_iter().map(LightState::into),
        )
        .await
        .expect("set completed")
        .expect("set successful");
}

/// Compares a vector of light group from the settings FIDL API and the light groups from a
/// service-internal LightInfo object for equality.
fn assert_lights_eq(mut groups: Vec<fidl_fuchsia_settings::LightGroup>, info: LightInfo) {
    // Watch returns vector, internally we use a HashMap, so convert into a vector for comparison.
    let mut expected_value = info
        .light_groups
        .into_iter()
        .map(|(_, value)| fidl_fuchsia_settings::LightGroup::from(value))
        .collect::<Vec<_>>();

    // Sort by names for stability
    groups.sort_by_key(|group: &fidl_fuchsia_settings::LightGroup| group.name.clone());
    expected_value.sort_by_key(|group| group.name.clone());
    assert_eq!(groups, expected_value);
}

#[fuchsia_async::run_until_stalled(test)]
async fn test_light_restore() {
    // Populate the fake service with the initial lights that will be restored.
    let hardware_light_service_handle = Arc::new(Mutex::new(HardwareLightService::new()));
    populate_single_test_lights(hardware_light_service_handle.clone(), get_test_light_info()).await;

    let (light_service, store) =
        create_test_light_env_with_service(None, Some(hardware_light_service_handle)).await;

    let expected_light_group = get_test_light_info().light_groups.remove(LIGHT_NAME_1).unwrap();

    // Verify that the restored value is persisted.
    let mut store_lock = store.lock().await;
    let retrieved_struct = store_lock.get().await;
    assert_eq!(
        &expected_light_group.clone(),
        retrieved_struct.light_groups.get(LIGHT_NAME_1).unwrap()
    );

    // Verify that the restored value is returned on a watch call.
    let settings: fidl_fuchsia_settings::LightGroup =
        light_service.watch_light_group(LIGHT_NAME_1).await.expect("watch completed");
    assert_eq!(fidl_fuchsia_settings::LightGroup::from(expected_light_group), settings);
}

#[fuchsia_async::run_until_stalled(test)]
async fn test_light_restores_on_watch() {
    let hardware_light_service_handle = Arc::new(Mutex::new(HardwareLightService::new()));

    let (light_service, _) =
        create_test_light_env_with_service(None, Some(hardware_light_service_handle.clone())).await;

    // Don't populate the fake service with lights until after the service starts.
    let expected_light_info = get_test_light_info();
    populate_single_test_lights(hardware_light_service_handle.clone(), expected_light_info.clone())
        .await;

    // Upon a watch call, light controller will read the underlying value from the fake service.
    let settings = light_service.watch_light_groups().await.expect("watch completed");
    assert_lights_eq(settings, expected_light_info);
}

#[fuchsia_async::run_until_stalled(test)]
async fn test_light_store_and_watch() {
    let mut expected_light_info = get_test_light_info();
    let mut changed_light_group =
        expected_light_info.light_groups.get(LIGHT_NAME_1).unwrap().clone();
    changed_light_group.lights = vec![LightState { value: Some(LightValue::Brightness(128)) }];
    expected_light_info.light_groups.insert(LIGHT_NAME_1.to_string(), changed_light_group.clone());

    let (light_service, store) =
        create_test_light_env_with_service(Some(get_test_light_info()), None).await;

    // Set a light value.
    set_light_value(&light_service, changed_light_group).await;

    // Verify the value we set is persisted in DeviceStorage.
    assert_eq!(expected_light_info, store.lock().await.get().await);

    // Ensure value from Watch matches set value.
    let settings: Vec<fidl_fuchsia_settings::LightGroup> =
        light_service.watch_light_groups().await.expect("watch completed");
    assert_lights_eq(settings, expected_light_info);
}

#[fuchsia_async::run_until_stalled(test)]
async fn test_light_set_wrong_size() {
    let (light_service, _) =
        create_test_light_env_with_service(Some(get_test_light_info()), None).await;

    // Light group only has one light, attempt to set two lights.
    light_service
        .set_light_group_values(
            LIGHT_NAME_1,
            &mut vec![
                LightState { value: Some(LightValue::Brightness(128)) },
                LightState { value: Some(LightValue::Brightness(11)) },
            ]
            .into_iter()
            .map(LightState::into),
        )
        .await
        .expect("set completed")
        .expect_err("set failed");
}

#[fuchsia_async::run_until_stalled(test)]
async fn test_light_set_none() {
    const TEST_LIGHT_NAME: &str = "multiple_lights";
    const LIGHT_1_VAL: u8 = 42;
    const LIGHT_2_START_VAL: u8 = 24;
    const LIGHT_2_CHANGED_VAL: u8 = 11;
    // For this test, create a light group with two lights to test setting one light at a time.
    let original_light_group = LightGroup {
        name: TEST_LIGHT_NAME.to_string(),
        enabled: true,
        light_type: LightType::Brightness,
        lights: vec![
            LightState { value: Some(LightValue::Brightness(LIGHT_1_VAL)) },
            LightState { value: Some(LightValue::Brightness(LIGHT_2_START_VAL)) },
        ],
        hardware_index: vec![0, 1],
    };

    // When changing the light group, specify None for the first light.
    let mut changed_light_group = original_light_group.clone();
    changed_light_group.lights = vec![
        LightState { value: None },
        LightState { value: Some(LightValue::Brightness(LIGHT_2_CHANGED_VAL)) },
    ];

    // Only the second light shoudl change.
    let mut expected_light_group = original_light_group.clone();
    expected_light_group.lights = vec![
        LightState { value: Some(LightValue::Brightness(LIGHT_1_VAL)) },
        LightState { value: Some(LightValue::Brightness(LIGHT_2_CHANGED_VAL)) },
    ];

    let mut light_groups = HashMap::new();
    light_groups.insert(TEST_LIGHT_NAME.to_string(), original_light_group);
    let starting_light_info = LightInfo { light_groups };

    let mut expected_light_info = starting_light_info.clone();
    expected_light_info
        .light_groups
        .insert(TEST_LIGHT_NAME.to_string(), expected_light_group.clone());

    let hardware_light_service_handle = Arc::new(Mutex::new(HardwareLightService::new()));

    let (light_service, store) = create_test_light_env_with_service(
        Some(starting_light_info.clone()),
        Some(hardware_light_service_handle.clone()),
    )
    .await;

    // Populate the fake service with the initial lights so the set calls aren't rejected.
    populate_multiple_test_lights(hardware_light_service_handle, starting_light_info).await;

    set_light_value(&light_service, changed_light_group).await;

    // Verify the value we set is persisted in DeviceStorage.
    assert_eq!(expected_light_info, store.lock().await.get().await);

    // Ensure value from Watch matches set value.
    let mut settings: Vec<fidl_fuchsia_settings::LightGroup> =
        light_service.watch_light_groups().await.expect("watch completed");
    settings.sort_by_key(|group: &fidl_fuchsia_settings::LightGroup| group.name.clone());

    let settings = light_service.watch_light_group(TEST_LIGHT_NAME).await.expect("watch completed");
    assert_eq!(settings, expected_light_group.into());
}

#[fuchsia_async::run_until_stalled(test)]
async fn test_individual_light_group() {
    let test_light_info = get_test_light_info();
    let light_group_1 = test_light_info.light_groups.get(LIGHT_NAME_1).unwrap().clone();
    let mut light_group_1_updated = light_group_1.clone();
    light_group_1_updated.lights = vec![LightState { value: Some(LightValue::Brightness(128)) }];

    let light_group_2 = test_light_info.light_groups.get(LIGHT_NAME_2).unwrap().clone();
    let mut light_group_2_updated = light_group_2.clone();
    light_group_2_updated.lights = vec![LightState { value: Some(LightValue::Simple(false)) }];

    let (light_service, _) =
        create_test_light_env_with_service(Some(get_test_light_info()), None).await;

    // Ensure values from Watch matches set values.
    let settings = light_service.watch_light_group(LIGHT_NAME_1).await.expect("watch completed");
    assert_eq!(settings, light_group_1.into());
    let settings = light_service.watch_light_group(LIGHT_NAME_2).await.expect("watch completed");
    assert_eq!(settings, light_group_2.into());

    // Set updated values for the two lights.
    set_light_value(&light_service, light_group_1_updated.clone()).await;

    let settings = light_service.watch_light_group(LIGHT_NAME_1).await.expect("watch completed");
    assert_eq!(settings, light_group_1_updated.into());

    set_light_value(&light_service, light_group_2_updated.clone()).await;

    let settings = light_service.watch_light_group(LIGHT_NAME_2).await.expect("watch completed");
    assert_eq!(settings, light_group_2_updated.into());
}

#[fuchsia_async::run_until_stalled(test)]
async fn test_watch_unknown_light_group_name() {
    let (light_service, _) =
        create_test_light_env_with_service(Some(get_test_light_info()), None).await;

    // Unknown name should be rejected.
    light_service.watch_light_group("unknown_name").await.expect_err("watch should fail");
}

#[fuchsia_async::run_until_stalled(test)]
async fn test_set_unknown_light_group_name() {
    let (light_service, _) =
        create_test_light_env_with_service(Some(get_test_light_info()), None).await;

    // Unknown name should be rejected.
    let result = light_service
        .set_light_group_values("unknown_name", &mut vec![].into_iter())
        .await
        .expect("set returns");
    assert_eq!(result, Err(LightError::InvalidName));
}

#[fuchsia_async::run_until_stalled(test)]
async fn test_set_wrong_state_length() {
    let test_light_info = get_test_light_info();
    let (light_service, _) = create_test_light_env_with_service(Some(test_light_info), None).await;

    // Set with no light state should fail.
    let result = light_service
        .set_light_group_values(LIGHT_NAME_1, &mut vec![].into_iter())
        .await
        .expect("set returns");
    assert_eq!(result, Err(LightError::InvalidValue));

    // Set with an extra light state should fail.
    let extra_state = vec![
        fidl_fuchsia_settings::LightState { value: None },
        fidl_fuchsia_settings::LightState { value: None },
    ];
    let result = light_service
        .set_light_group_values(LIGHT_NAME_1, &mut extra_state.into_iter())
        .await
        .expect("set returns");
    assert_eq!(result, Err(LightError::InvalidValue));
}

#[fuchsia_async::run_until_stalled(test)]
async fn test_set_wrong_value_type() {
    const TEST_LIGHT_NAME: &str = "multiple_lights";
    const LIGHT_START_VAL: u8 = 24;
    const LIGHT_CHANGED_VAL: u8 = 11;
    let original_light_group = LightGroup {
        name: TEST_LIGHT_NAME.to_string(),
        enabled: true,
        light_type: LightType::Brightness,
        lights: vec![
            LightState { value: Some(LightValue::Brightness(LIGHT_START_VAL)) },
            LightState { value: Some(LightValue::Brightness(LIGHT_START_VAL)) },
        ],
        hardware_index: vec![0, 1],
    };
    let mut light_groups = HashMap::new();
    light_groups.insert(TEST_LIGHT_NAME.to_string(), original_light_group);
    let starting_light_info = LightInfo { light_groups };

    let hardware_light_service_handle = Arc::new(Mutex::new(HardwareLightService::new()));

    let (light_service, _) = create_test_light_env_with_service(
        Some(starting_light_info.clone()),
        Some(hardware_light_service_handle.clone()),
    )
    .await;

    // One of the light values is On instead of brightness, the set should fail.
    let result = light_service
        .set_light_group_values(
            TEST_LIGHT_NAME,
            &mut vec![
                fidl_fuchsia_settings::LightState { value: None },
                fidl_fuchsia_settings::LightState {
                    value: Some(fidl_fuchsia_settings::LightValue::On(true)),
                },
            ]
            .into_iter(),
        )
        .await
        .expect("set returns");
    assert_eq!(result, Err(LightError::InvalidValue));

    // One of the values is the right type, but the other is still wrong, the set should fail.
    let result = light_service
        .set_light_group_values(
            TEST_LIGHT_NAME,
            &mut vec![
                fidl_fuchsia_settings::LightState {
                    value: Some(fidl_fuchsia_settings::LightValue::Brightness(LIGHT_CHANGED_VAL)),
                },
                fidl_fuchsia_settings::LightState {
                    value: Some(fidl_fuchsia_settings::LightValue::On(true)),
                },
            ]
            .into_iter(),
        )
        .await
        .expect("set returns");
    assert_eq!(result, Err(LightError::InvalidValue));
}

#[fuchsia_async::run_until_stalled(test)]
async fn test_set_invalid_rgb_values() {
    const TEST_LIGHT_NAME: &str = "light";
    const LIGHT_START_VAL: f32 = 0.25;
    const INVALID_VAL_1: f32 = 1.1;
    const INVALID_VAL_2: f32 = -0.1;
    let original_light_group = LightGroup {
        name: TEST_LIGHT_NAME.to_string(),
        enabled: true,
        light_type: LightType::Rgb,
        lights: vec![LightState {
            value: Some(LightValue::Rgb(ColorRgb {
                red: LIGHT_START_VAL,
                green: LIGHT_START_VAL,
                blue: LIGHT_START_VAL,
            })),
        }],
        hardware_index: vec![0],
    };
    let mut light_groups = HashMap::new();
    light_groups.insert(TEST_LIGHT_NAME.to_string(), original_light_group);
    let starting_light_info = LightInfo { light_groups };

    let hardware_light_service_handle = Arc::new(Mutex::new(HardwareLightService::new()));

    let (light_service, _) = create_test_light_env_with_service(
        Some(starting_light_info.clone()),
        Some(hardware_light_service_handle.clone()),
    )
    .await;

    // One of the RGB components is too big, the set should fail.
    let result = light_service
        .set_light_group_values(
            TEST_LIGHT_NAME,
            &mut vec![fidl_fuchsia_settings::LightState {
                value: Some(fidl_fuchsia_settings::LightValue::Color(
                    fidl_fuchsia_ui_types::ColorRgb {
                        red: LIGHT_START_VAL,
                        green: LIGHT_START_VAL,
                        blue: INVALID_VAL_1,
                    },
                )),
            }]
            .into_iter(),
        )
        .await
        .expect("set returns");
    assert_eq!(result, Err(LightError::InvalidValue));

    // One of the RGB components is negative, the set should fail.
    let result = light_service
        .set_light_group_values(
            TEST_LIGHT_NAME,
            &mut vec![fidl_fuchsia_settings::LightState {
                value: Some(fidl_fuchsia_settings::LightValue::Color(
                    fidl_fuchsia_ui_types::ColorRgb {
                        red: LIGHT_START_VAL,
                        green: INVALID_VAL_2,
                        blue: LIGHT_START_VAL,
                    },
                )),
            }]
            .into_iter(),
        )
        .await
        .expect("set returns");
    assert_eq!(result, Err(LightError::InvalidValue));
}
