// Copyright 2022 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::common::{FactoryResetTest, Mocks};
use anyhow::Error;
use async_trait::async_trait;
use fidl_fuchsia_recovery_policy::{DeviceRequest, DeviceRequestStream};
use fuchsia_async as fasync;
use fuchsia_component::server::{ServiceFs, ServiceFsDir};
use fuchsia_component_test::LocalComponentHandles;
use futures::channel::mpsc::Sender;
use futures::{SinkExt, StreamExt, TryStreamExt};
mod common;

#[async_trait]
impl Mocks for FactoryResetTest {
    async fn recovery_policy_impl(
        handles: LocalComponentHandles,
        reset_allowed_sender: Sender<bool>,
    ) -> Result<(), Error> {
        let mut fs = ServiceFs::new();
        let _: &mut ServiceFsDir<'_, _> =
            fs.dir("svc").add_fidl_service(move |mut stream: DeviceRequestStream| {
                let mut reset_allowed_sender = reset_allowed_sender.clone();
                fasync::Task::spawn(async move {
                    while let Ok(Some(req)) = stream.try_next().await {
                        // Support future expansion of FIDL.
                        #[allow(unreachable_patterns)]
                        #[allow(clippy::single_match)]
                        match req {
                            DeviceRequest::SetIsLocalResetAllowed {
                                allowed,
                                control_handle: _,
                            } => {
                                reset_allowed_sender
                                    .send(allowed)
                                    .await
                                    .expect("Sent allowed value from SetIsLocalResetAllowed call");
                            }
                            _ => {}
                        }
                    }
                })
                .detach();
            });
        let _ = fs.serve_connection(handles.outgoing_dir)?;
        fs.collect::<()>().await;
        Ok(())
    }
}

// Tests that the FIDL calls for the reset setting result in appropriate
// commands sent to the service.
#[fuchsia::test]
async fn test_set() {
    // This bounded channel is initialized with 0 initial capacity so that the sender (which adds 1
    // capacity) can only send one message at a time, so that we can more closely verify when the
    // mock receives requests. This makes it so that if the mock receives two requests in a row
    // without the test verifying at least the first one, the test will fail in order to indicate
    // something unexpected has happened.
    let (reset_allowed_sender, mut reset_allowed_receiver) =
        futures::channel::mpsc::channel::<bool>(0);
    let instance =
        FactoryResetTest::create_realm(reset_allowed_sender).await.expect("setting up test realm");

    let proxy = FactoryResetTest::connect_to_factoryresetmarker(&instance);

    // Verify that the value is true by default.
    let settings = proxy.watch().await.expect("watch completed");
    assert_eq!(settings.is_local_reset_allowed, Some(true));

    // Verify that the mock receives a value of true for the setting on service start.
    assert_eq!(Some(true), reset_allowed_receiver.next().await);

    // Update the value to false.
    proxy
        .set(&fidl_fuchsia_settings::FactoryResetSettings {
            is_local_reset_allowed: Some(false),
            ..Default::default()
        })
        .await
        .expect("set completed")
        .expect("set successful");

    // Verify that the mock receives a value of false for the setting after the set call.
    assert_eq!(Some(false), reset_allowed_receiver.next().await);

    let _ = instance.destroy().await;
}
