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

#[cfg(test)]
use {
    crate::audio::{
        create_default_audio_stream, spawn_audio_controller, spawn_audio_fidl_handler,
        DEFAULT_STREAMS,
    },
    crate::create_fidl_service,
    crate::fidl_clone::FIDLClone,
    crate::registry::base::Registry,
    crate::registry::device_storage::testing::*,
    crate::registry::registry_impl::RegistryImpl,
    crate::registry::service_context::ServiceContext,
    crate::switchboard::base::{
        AudioInfo, AudioInputInfo, AudioStream, AudioStreamType, SettingAction, SettingType,
    },
    crate::switchboard::switchboard_impl::SwitchboardImpl,
    crate::tests::fakes::audio_core_service::AudioCoreService,
    crate::tests::fakes::input_device_registry_service::InputDeviceRegistryService,
    crate::tests::fakes::service_registry::ServiceRegistry,
    fidl_fuchsia_media::AudioRenderUsage,
    fidl_fuchsia_settings::*,
    fidl_fuchsia_ui_input::MediaButtonsEvent,
    fuchsia_async as fasync,
    fuchsia_component::server::{ServiceFs, ServiceFsDir, ServiceObj},
    futures::prelude::*,
    parking_lot::RwLock,
    std::sync::Arc,
};

const ENV_NAME: &str = "settings_service_audio_test_environment";

const DEFAULT_MEDIA_STREAM: AudioStream = create_default_audio_stream(AudioStreamType::Media);
const DEFAULT_SYSTEM_STREAM: AudioStream =
    create_default_audio_stream(AudioStreamType::SystemAgent);

const CHANGED_VOLUME_LEVEL: f32 = 0.7;
const CHANGED_VOLUME_MUTED: bool = true;

const CHANGED_MEDIA_STREAM: AudioStreamSettings = AudioStreamSettings {
    stream: Some(fidl_fuchsia_media::AudioRenderUsage::Media),
    source: Some(AudioStreamSettingSource::User),
    user_volume: Some(Volume {
        level: Some(CHANGED_VOLUME_LEVEL),
        muted: Some(CHANGED_VOLUME_MUTED),
    }),
};

async fn set_volume(proxy: &AudioProxy, streams: Vec<AudioStreamSettings>) {
    let mut audio_settings = AudioSettings::empty();
    audio_settings.streams = Some(streams);
    proxy.set(audio_settings).await.expect("set completed").expect("set successful");
}

// Verifies that a stream equal to |stream| is inside of |settings|.
fn verify_audio_stream(settings: AudioSettings, stream: AudioStreamSettings) {
    settings
        .streams
        .expect("audio settings contain streams")
        .into_iter()
        .find(|x| *x == stream)
        .expect("contains stream");
}

// Returns a registry and audio related services it is populated with
fn create_services() -> (
    Arc<RwLock<ServiceRegistry>>,
    Arc<RwLock<AudioCoreService>>,
    Arc<RwLock<InputDeviceRegistryService>>,
) {
    let service_registry = ServiceRegistry::create();
    let audio_core_service_handle = Arc::new(RwLock::new(AudioCoreService::new()));
    service_registry.write().register_service(audio_core_service_handle.clone());
    let input_device_registry_service_handle =
        Arc::new(RwLock::new(InputDeviceRegistryService::new()));
    service_registry.write().register_service(input_device_registry_service_handle.clone());

    return (service_registry, audio_core_service_handle, input_device_registry_service_handle);
}

// This function is created so that we can manipulate the |pair_media_and_system_agent| flag.
// TODO(go/fxb/37493): Remove this function and the related tests when the hack is removed.
fn create_audio_fidl_service<'a>(
    mut service_dir: ServiceFsDir<ServiceObj<'a, ()>>,
    service_registry_handle: Arc<RwLock<ServiceRegistry>>,
    pair_media_and_system_agent: bool,
) {
    let (action_tx, action_rx) = futures::channel::mpsc::unbounded::<SettingAction>();

    // Creates switchboard, handed to interface implementations to send messages
    // to handlers.
    let (switchboard_handle, event_tx) = SwitchboardImpl::create(action_tx);

    let service_context_handle = Arc::new(RwLock::new(ServiceContext::new(
        ServiceRegistry::serve(service_registry_handle.clone()),
    )));

    // Creates registry, used to register handlers for setting types.
    let registry_handle = RegistryImpl::create(event_tx, action_rx);
    registry_handle
        .write()
        .register(
            SettingType::Audio,
            spawn_audio_controller(service_context_handle.clone(), pair_media_and_system_agent),
        )
        .unwrap();

    let switchboard_handle_clone = switchboard_handle.clone();
    service_dir.add_fidl_service(move |stream: AudioRequestStream| {
        spawn_audio_fidl_handler(switchboard_handle_clone.clone(), stream);
    });
}

#[fuchsia_async::run_singlethreaded(test)]
async fn test_audio() {
    let (service_registry, audio_core_service_handle, _) = create_services();

    let mut fs = ServiceFs::new();

    create_fidl_service(
        fs.root_dir(),
        [SettingType::Audio].iter().cloned().collect(),
        Arc::new(RwLock::new(ServiceContext::new(ServiceRegistry::serve(
            service_registry.clone(),
        )))),
        Box::new(InMemoryStorageFactory::create()),
    );

    let env = fs.create_salted_nested_environment(ENV_NAME).unwrap();
    fasync::spawn(fs.collect());

    let audio_proxy = env.connect_to_service::<AudioMarker>().unwrap();

    let settings = audio_proxy.watch().await.expect("watch completed").expect("watch successful");
    verify_audio_stream(settings.clone(), AudioStreamSettings::from(DEFAULT_MEDIA_STREAM));

    set_volume(&audio_proxy, vec![CHANGED_MEDIA_STREAM]).await;
    let settings = audio_proxy.watch().await.expect("watch completed").expect("watch successful");
    verify_audio_stream(settings.clone(), AudioStreamSettings::from(CHANGED_MEDIA_STREAM));

    assert_eq!(
        (CHANGED_VOLUME_LEVEL, CHANGED_VOLUME_MUTED),
        audio_core_service_handle.read().get_level_and_mute(AudioRenderUsage::Media).unwrap()
    );

    assert_eq!(2, audio_core_service_handle.read().get_ack_count(AudioRenderUsage::Media).unwrap());
}

// Test to ensure mic input change events are received.
#[fuchsia_async::run_singlethreaded(test)]
async fn test_audio_input() {
    let (service_registry, _, input_service_handle) = create_services();

    let mut fs = ServiceFs::new();

    create_fidl_service(
        fs.root_dir(),
        [SettingType::Audio].iter().cloned().collect(),
        Arc::new(RwLock::new(ServiceContext::new(ServiceRegistry::serve(
            service_registry.clone(),
        )))),
        Box::new(InMemoryStorageFactory::create()),
    );

    let env = fs.create_salted_nested_environment(ENV_NAME).unwrap();
    fasync::spawn(fs.collect());

    let audio_proxy = env.connect_to_service::<AudioMarker>().unwrap();

    let buttons_event = MediaButtonsEvent { volume: Some(1), mic_mute: Some(true) };
    input_service_handle.read().send_media_button_event(buttons_event.clone());

    let updated_settings =
        audio_proxy.watch().await.expect("watch completed").expect("watch successful");
    if let Some(input) = updated_settings.input {
        if let Some(mic_mute) = input.muted {
            assert!(mic_mute);
        } else {
            panic!("should have mic mute value");
        }
    } else {
        panic!("should have input settings");
    }
}

// Test to ensure mic input change events are received.
#[fuchsia_async::run_singlethreaded(test)]
async fn test_bringup_without_input_registry() {
    let service_registry = ServiceRegistry::create();
    let audio_core_service_handle = Arc::new(RwLock::new(AudioCoreService::new()));
    service_registry.write().register_service(audio_core_service_handle.clone());

    let mut fs = ServiceFs::new();

    create_fidl_service(
        fs.root_dir(),
        [SettingType::Audio].iter().cloned().collect(),
        Arc::new(RwLock::new(ServiceContext::new(ServiceRegistry::serve(
            service_registry.clone(),
        )))),
        Box::new(InMemoryStorageFactory::create()),
    );

    let env = fs.create_salted_nested_environment(ENV_NAME).unwrap();
    fasync::spawn(fs.collect());

    // At this point we should not crash.
    assert!(env.connect_to_service::<AudioMarker>().is_ok());
}

// Test to ensure that when |pair_media_and_system_agent| is enabled, setting the media volume
// without a system agent volume will change the system agent volume.
#[fuchsia_async::run_singlethreaded(test)]
async fn test_audio_pair_media_system() {
    let mut changed_system_stream = CHANGED_MEDIA_STREAM.clone();
    changed_system_stream.stream = Some(fidl_fuchsia_media::AudioRenderUsage::SystemAgent);

    let (service_registry, audio_core_service_handle, _) = create_services();

    let mut fs = ServiceFs::new();

    create_audio_fidl_service(fs.root_dir(), service_registry.clone(), true);

    let env = fs.create_salted_nested_environment(ENV_NAME).unwrap();
    fasync::spawn(fs.collect());

    let audio_proxy = env.connect_to_service::<AudioMarker>().unwrap();

    let settings = audio_proxy.watch().await.expect("watch completed").expect("watch successful");
    verify_audio_stream(settings.clone(), AudioStreamSettings::from(DEFAULT_MEDIA_STREAM));
    verify_audio_stream(settings.clone(), AudioStreamSettings::from(DEFAULT_SYSTEM_STREAM));

    set_volume(&audio_proxy, vec![CHANGED_MEDIA_STREAM]).await;

    let settings = audio_proxy.watch().await.expect("watch completed").expect("watch successful");
    verify_audio_stream(settings.clone(), AudioStreamSettings::from(CHANGED_MEDIA_STREAM));
    verify_audio_stream(settings.clone(), AudioStreamSettings::from(changed_system_stream));

    assert_eq!(
        (CHANGED_VOLUME_LEVEL, CHANGED_VOLUME_MUTED),
        audio_core_service_handle.read().get_level_and_mute(AudioRenderUsage::Media).unwrap()
    );
    assert_eq!(
        (CHANGED_VOLUME_LEVEL, CHANGED_VOLUME_MUTED),
        audio_core_service_handle.read().get_level_and_mute(AudioRenderUsage::SystemAgent).unwrap()
    );

    assert_eq!(2, audio_core_service_handle.read().get_ack_count(AudioRenderUsage::Media).unwrap());
    assert_eq!(
        2,
        audio_core_service_handle.read().get_ack_count(AudioRenderUsage::SystemAgent).unwrap()
    );
}

// Test to ensure that when |pair_media_and_system_agent| is disabled, setting the media volume will
// not affect the system agent volume.
#[fuchsia_async::run_singlethreaded(test)]
async fn test_audio_pair_media_system_off() {
    let (service_registry, audio_core_service_handle, _) = create_services();

    let mut fs = ServiceFs::new();

    create_audio_fidl_service(fs.root_dir(), service_registry.clone(), false);

    let env = fs.create_salted_nested_environment(ENV_NAME).unwrap();
    fasync::spawn(fs.collect());

    let audio_proxy = env.connect_to_service::<AudioMarker>().unwrap();

    let settings = audio_proxy.watch().await.expect("watch completed").expect("watch successful");
    verify_audio_stream(settings.clone(), AudioStreamSettings::from(DEFAULT_MEDIA_STREAM));
    verify_audio_stream(settings.clone(), AudioStreamSettings::from(DEFAULT_SYSTEM_STREAM));

    set_volume(&audio_proxy, vec![CHANGED_MEDIA_STREAM]).await;

    let settings = audio_proxy.watch().await.expect("watch completed").expect("watch successful");
    verify_audio_stream(settings.clone(), AudioStreamSettings::from(CHANGED_MEDIA_STREAM));
    verify_audio_stream(settings.clone(), AudioStreamSettings::from(DEFAULT_SYSTEM_STREAM));

    assert_eq!(
        (CHANGED_VOLUME_LEVEL, CHANGED_VOLUME_MUTED),
        audio_core_service_handle.read().get_level_and_mute(AudioRenderUsage::Media).unwrap()
    );

    assert_eq!(
        None,
        audio_core_service_handle.read().get_level_and_mute(AudioRenderUsage::SystemAgent)
    );

    assert_eq!(2, audio_core_service_handle.read().get_ack_count(AudioRenderUsage::Media).unwrap());
    assert_eq!(None, audio_core_service_handle.read().get_ack_count(AudioRenderUsage::SystemAgent));
}

// Test to ensure that when |pair_media_and_system_agent| is enabled, setting the media volume
// with the system agent volume will not set to the system agent volume to the media volume.
#[fuchsia_async::run_singlethreaded(test)]
async fn test_audio_pair_media_system_with_system_agent_change() {
    let (service_registry, audio_core_service_handle, _) = create_services();

    let mut fs = ServiceFs::new();

    create_audio_fidl_service(fs.root_dir(), service_registry.clone(), true);

    let env = fs.create_salted_nested_environment(ENV_NAME).unwrap();
    fasync::spawn(fs.collect());

    let audio_proxy = env.connect_to_service::<AudioMarker>().unwrap();

    let settings = audio_proxy.watch().await.expect("watch completed").expect("watch successful");
    verify_audio_stream(settings.clone(), AudioStreamSettings::from(DEFAULT_MEDIA_STREAM));
    verify_audio_stream(settings.clone(), AudioStreamSettings::from(DEFAULT_SYSTEM_STREAM));

    const CHANGED_SYSTEM_LEVEL: f32 = 0.2;
    const CHANGED_SYSTEM_MUTED: bool = false;
    const CHANGED_SYSTEM_STREAM: AudioStreamSettings = AudioStreamSettings {
        stream: Some(fidl_fuchsia_media::AudioRenderUsage::SystemAgent),
        source: Some(AudioStreamSettingSource::User),
        user_volume: Some(Volume {
            level: Some(CHANGED_SYSTEM_LEVEL),
            muted: Some(CHANGED_SYSTEM_MUTED),
        }),
    };

    set_volume(&audio_proxy, vec![CHANGED_MEDIA_STREAM, CHANGED_SYSTEM_STREAM.clone()]).await;

    let settings = audio_proxy.watch().await.expect("watch completed").expect("watch successful");
    verify_audio_stream(settings.clone(), AudioStreamSettings::from(CHANGED_MEDIA_STREAM));
    verify_audio_stream(settings.clone(), AudioStreamSettings::from(CHANGED_SYSTEM_STREAM));

    assert_eq!(
        (CHANGED_VOLUME_LEVEL, CHANGED_VOLUME_MUTED),
        audio_core_service_handle.read().get_level_and_mute(AudioRenderUsage::Media).unwrap()
    );

    assert_eq!(
        (CHANGED_SYSTEM_LEVEL, CHANGED_SYSTEM_MUTED),
        audio_core_service_handle.read().get_level_and_mute(AudioRenderUsage::SystemAgent).unwrap()
    );

    assert_eq!(2, audio_core_service_handle.read().get_ack_count(AudioRenderUsage::Media).unwrap());
    assert_eq!(
        1,
        audio_core_service_handle.read().get_ack_count(AudioRenderUsage::SystemAgent).unwrap()
    );
}

#[fuchsia_async::run_singlethreaded(test)]
async fn test_audio_info_copy() {
    let audio_info =
        AudioInfo { streams: DEFAULT_STREAMS, input: AudioInputInfo { mic_mute: false } };

    let copy_audio_info = audio_info;
    assert_eq!(audio_info, copy_audio_info);
}
