// 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 {
    anyhow::{format_err, Error},
    fidl::endpoints::RequestStream,
    fuchsia_async::{DurationExt, TimeoutExt},
    fuchsia_zircon::Duration,
    futures::{TryStream, TryStreamExt},
};

/// Represents the status of an expectation over a FIDL request stream.
pub(crate) enum Status<T> {
    Pending,
    Satisfied(T),
}

/// Asynchronously applies handler `H` to each FIDL request of type `R` received from stream `S`
/// until the handler is satisfied or the provided timeout expires.
pub(crate) async fn expect_call<H, T, R, S>(
    stream: &mut S,
    timeout: Duration,
    mut handler: H,
) -> Result<T, Error>
where
    H: FnMut(R) -> Result<Status<T>, Error>,
    S: RequestStream + TryStream<Ok = R, Error = fidl::Error>,
{
    async {
        while let Some(msg) = stream.try_next().await? {
            match handler(msg)? {
                Status::Satisfied(t) => {
                    return Ok(t);
                }
                Status::Pending => (),
            }
        }
        Err(format_err!("Stream closed before expectation was satisifed"))
    }
    .on_timeout(timeout.after_now(), || {
        Err(format_err!("timed out before expectation was satisfied"))
    })
    .await
}

#[cfg(test)]
mod tests {
    use super::*;
    use {
        fidl::endpoints::create_proxy_and_stream,
        fidl_fuchsia_bluetooth::DeviceClass,
        fidl_fuchsia_bluetooth_sys::{AccessMarker, AccessRequest, AccessRequestStream},
        fuchsia_zircon::DurationNum,
    };

    // This is a mock handler that does the following for the purposes of the unit tests below:
    // - Return success if Access.SetLocalName is called with the given `expected_name`;
    // - Return an error if Access.SetLocalName is called with a name that is different from
    //   `expected_name`;
    // - Continue expecting a message if any other FIDL message is received.
    async fn expect_set_local_name(
        mut stream: AccessRequestStream,
        expected_name: String,
    ) -> Result<(), Error> {
        expect_call(&mut stream, 500.millis(), move |req| match req {
            AccessRequest::SetLocalName { name, control_handle: _ } => {
                if name == expected_name {
                    Ok(Status::Satisfied(()))
                } else {
                    Err(format_err!("received incorrect name"))
                }
            }
            _ => Ok(Status::Pending),
        })
        .await
    }

    #[fuchsia_async::run_until_stalled(test)]
    async fn test_satisfied() {
        let (proxy, stream) =
            create_proxy_and_stream::<AccessMarker>().expect("failed to create proxy");
        let name = "TEST".to_string();

        let _ = proxy.set_local_name(&name);
        let mock_result = expect_set_local_name(stream, name).await;
        assert!(mock_result.is_ok());
    }

    #[fuchsia_async::run_until_stalled(test)]
    async fn test_unsatisfied_due_to_mismatch() {
        let (proxy, stream) =
            create_proxy_and_stream::<AccessMarker>().expect("failed to create proxy");
        let expected_name = "TEST".to_string();
        let wrong_name = "💩".to_string();

        let _ = proxy.set_local_name(&wrong_name);
        let mock_result = expect_set_local_name(stream, expected_name).await;
        assert!(mock_result.is_err());
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_timeout_without_any_message() {
        let (_proxy, stream) =
            create_proxy_and_stream::<AccessMarker>().expect("failed to create proxy");
        let expected_name = "TEST".to_string();
        let result = expect_set_local_name(stream, expected_name).await;
        assert!(result.is_err());
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_timeout_after_unexpected_message() {
        let (proxy, stream) =
            create_proxy_and_stream::<AccessMarker>().expect("failed to create proxy");
        let expected_name = "TEST".to_string();

        let _ = proxy.set_device_class(&DeviceClass { value: 0 });
        let mock_result = expect_set_local_name(stream, expected_name).await;
        assert!(mock_result.is_err());
    }

    #[fuchsia_async::run_until_stalled(test)]
    async fn test_error_after_handle_closure() {
        let (proxy, stream) =
            create_proxy_and_stream::<AccessMarker>().expect("failed to create proxy");
        let expected_name = "TEST".to_string();

        drop(proxy);
        let result = expect_set_local_name(stream, expected_name).await;
        assert!(result.is_err());
    }

    #[fuchsia_async::run_until_stalled(test)]
    async fn test_satisfied_with_expected_message_after_unexpected_message() {
        let (proxy, stream) =
            create_proxy_and_stream::<AccessMarker>().expect("failed to create proxy");
        let expected_name = "TEST".to_string();

        let _ = proxy.set_device_class(&DeviceClass { value: 0 });
        let _ = proxy.set_local_name(&expected_name);
        let mock_result = expect_set_local_name(stream, expected_name.clone()).await;
        assert!(mock_result.is_ok());
    }
}
