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

//! Mock HttpsClient for use in testing.
//!
//! Usage:
//! ```
//! let mut https_client = HttpsClient::mock();
//! // Set up expected requests and responses (as many as needed, in the order
//! // they should happen).
//! https_client.expect(req, res);
//! // Use the https_client in-place of the normal https_client. As matching
//! // requests come in, the premade responses will be returned.
//! ```

use fuchsia_sync::Mutex;
use hyper::{Body, Request};
use std::collections::VecDeque;

#[derive(Debug)]
struct HttpsClientEvent {
    req: Request<Body>,
    res: http::Result<http::Response<Body>>,
}

#[derive(Debug)]
pub struct HttpsClient {
    expected: Mutex<VecDeque<HttpsClientEvent>>,
}

impl HttpsClient {
    /// Create a new mock https client.
    ///
    /// Consider adding expected events with `.expect(req, res)`.
    pub fn mock() -> Self {
        Self { expected: Mutex::new(VecDeque::new()) }
    }

    /// Append an expected request and response.
    ///
    /// Note that `res` is actually a Result<> type.
    pub fn expect(&mut self, req: Request<Body>, res: http::Result<http::Response<Body>>) {
        self.expected.lock().push_back(HttpsClientEvent { req, res });
    }

    pub async fn request(&self, req: Request<Body>) -> http::Result<http::Response<Body>> {
        let expected = self.expected.lock().pop_front().unwrap_or_else(|| {
            panic!(
                "Error: received more https requests than expected. \
            No response available for req: {:?}",
                req
            )
        });

        assert_eq!(
            expected.req.uri(),
            req.uri(),
            "mock_https_client actual {:?}, expected {:?}, related response {:?}",
            req,
            expected.req,
            expected.res
        );
        assert_eq!(expected.req.method(), req.method());
        let expected_bytes =
            hyper::body::to_bytes(expected.req.into_body()).await.expect("expected.req.into_body");
        let req_bytes = hyper::body::to_bytes(req.into_body()).await.expect("req.into_body");
        assert_eq!(expected_bytes, req_bytes);

        expected.res
    }
}

pub fn new_https_client() -> HttpsClient {
    HttpsClient::mock()
}

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

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_mock() {
        let mut https_client = HttpsClient::mock();

        let req = Request::builder()
            .method(Method::POST)
            .uri("https://example.com")
            .body(Body::from("alpha"))
            .expect("Request::builder");
        let builder = http::Response::builder().status(http::StatusCode::OK);
        let res = builder.body(Body::from("beta"));
        https_client.expect(req, res);

        let req = Request::builder()
            .method(Method::POST)
            .uri("https://example.com")
            .body(Body::from("alpha"))
            .expect("Request::builder");
        let res = https_client.request(req).await.expect("https_client.request");
        assert_eq!(res.status(), http::StatusCode::OK);
        let bytes = hyper::body::to_bytes(res.into_body()).await.expect("body::to_bytes");
        assert_eq!(b"beta", &bytes[..]);
    }

    #[should_panic(expected = "actual Request")]
    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_mock_fail() {
        let mut https_client = HttpsClient::mock();

        let req = Request::builder()
            .method(Method::POST)
            .uri("https://example.com")
            .body(Body::from("alpha"))
            .expect("Request::builder");
        let builder = http::Response::builder().status(http::StatusCode::OK);
        let res = builder.body(Body::from("beta"));
        https_client.expect(req, res);

        let req = Request::builder()
            .method(Method::POST)
            .uri("https://not-same.com")
            .body(Body::from("alpha"))
            .expect("Request::builder");
        let res = https_client.request(req).await.expect("https_client.request");
        assert_eq!(res.status(), http::StatusCode::OK);
    }

    #[test]
    fn test_new_https_client() {
        let https_client = new_https_client();
        assert!(https_client.expected.lock().is_empty());
    }
}
