// 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 crate::constants::USER_INFO_URI;
use crate::error::{ResultExt, TokenProviderError};
use crate::http::{HttpClient, HttpRequest, HttpRequestBuilder};
use crate::oauth::{self, AccessToken, RefreshToken};
use crate::time::Clock;
use fidl_fuchsia_identity_external::{
    Error as ApiError, OauthOpenIdConnectRequest, OauthOpenIdConnectRequestStream,
    OpenIdTokenFromOauthRefreshTokenRequest, OpenIdUserInfoFromOauthAccessTokenRequest,
};
use fidl_fuchsia_identity_tokens::{OpenIdToken, OpenIdUserInfo};
use fuchsia_zircon::Duration;
use futures::prelude::*;
use hyper::StatusCode;
use log::warn;
use serde::Deserialize;
use serde_json::from_str;
use std::marker::PhantomData;

type TokenProviderResult<T> = Result<T, TokenProviderError>;

/// An implementation of the `fuchsia.identity.external.OauthOpenIdConnect`
/// protocol that communicates with the Google identity system to perform
/// exchanges between Oauth 2.0 and OpenId Connect tokens.
pub struct OauthOpenIdConnect<HC, C>
where
    HC: HttpClient,
    C: Clock,
{
    /// A client used for making HTTP requests.
    http_client: HC,
    /// A marker denoting which clock implementation to use.
    _clock: PhantomData<C>,
}

impl<HC, C> OauthOpenIdConnect<HC, C>
where
    HC: HttpClient,
    C: Clock,
{
    /// Create a new GoogleAuthProvider.
    pub fn new(http_client: HC) -> Self {
        OauthOpenIdConnect { http_client, _clock: PhantomData }
    }

    /// Handle requests passed to the supplied stream.
    pub async fn handle_requests_from_stream(
        &self,
        mut stream: OauthOpenIdConnectRequestStream,
    ) -> Result<(), fidl::Error> {
        while let Some(request) = stream.try_next().await? {
            self.handle_request(request).await?;
        }
        Ok(())
    }

    async fn handle_request(&self, request: OauthOpenIdConnectRequest) -> Result<(), fidl::Error> {
        match request {
            OauthOpenIdConnectRequest::GetIdTokenFromRefreshToken { request, responder } => {
                let mut response =
                    self.get_id_token_from_refresh_token(request).await.map_err(|e| e.api_error);
                responder.send(&mut response).map_err(|e| {
                    warn!("Error sending response for GetIdTokenFromRefreshToken: {:?}", e);
                    e
                })
            }
            OauthOpenIdConnectRequest::GetUserInfoFromAccessToken { request, responder } => {
                let mut response =
                    self.get_user_info_from_access_token(request).await.map_err(|e| e.api_error);
                responder.send(&mut response).map_err(|e| {
                    warn!("Error sending response for GetUserInfoFromAccessToken: {:?}", e);
                    e
                })
            }
        }
    }

    async fn get_id_token_from_refresh_token(
        &self,
        request: OpenIdTokenFromOauthRefreshTokenRequest,
    ) -> TokenProviderResult<OpenIdToken> {
        let OpenIdTokenFromOauthRefreshTokenRequest { refresh_token, audiences, .. } = request;
        let refresh_token_contents = refresh_token
            .ok_or(TokenProviderError::new(ApiError::InvalidRequest))?
            .content
            .ok_or(TokenProviderError::new(ApiError::InvalidRequest))?;
        if refresh_token_contents.is_empty() {
            return Err(TokenProviderError::new(ApiError::InvalidRequest));
        }

        let audience = match audiences {
            None => None,
            Some(mut audiences) => match audiences.len() {
                0 => None,
                1 => Some(audiences.remove(0)),
                // TODO(satsukiu): support requests for multiple audiences
                _ => return Err(TokenProviderError::new(ApiError::UnsupportedOperation)),
            },
        };

        match audience.as_ref() {
            Some(aud) if aud.is_empty() => {
                return Err(TokenProviderError::new(ApiError::InvalidRequest))
            }
            _ => (),
        }

        let request = build_id_token_request(RefreshToken(refresh_token_contents), audience)?;
        let (response_body, status) = self.http_client.request(request).await?;
        let (id_token, expires_in) = parse_id_token_response(response_body, status)?;

        let expiry_time = C::current_time() + expires_in;
        Ok(OpenIdToken {
            content: Some(id_token.0),
            expiry_time: Some(expiry_time.into_nanos()),
            ..OpenIdToken::EMPTY
        })
    }

    async fn get_user_info_from_access_token(
        &self,
        request: OpenIdUserInfoFromOauthAccessTokenRequest,
    ) -> TokenProviderResult<OpenIdUserInfo> {
        let access_token_content = request
            .access_token
            .ok_or(TokenProviderError::new(ApiError::InvalidRequest))?
            .content
            .ok_or(TokenProviderError::new(ApiError::InvalidRequest))?;
        if access_token_content.is_empty() {
            return Err(TokenProviderError::new(ApiError::InvalidRequest));
        }

        let request = build_user_info_request(&AccessToken(access_token_content))?;
        let (response_body, status_code) = self.http_client.request(request).await?;
        let OpenIdUserInfoResponse { sub, name, email, picture, .. } =
            parse_user_info_response(response_body, status_code)?;
        Ok(OpenIdUserInfo { subject: Some(sub), name, email, picture, ..OpenIdUserInfo::EMPTY })
    }
}

#[derive(Debug, PartialEq)]
struct IdToken(pub String);

/// Response type for OpenID user info requests.
#[derive(Debug, Deserialize, PartialEq)]
pub struct OpenIdUserInfoResponse {
    pub sub: String,
    pub name: Option<String>,
    pub email: Option<String>,
    pub picture: Option<String>,
}

/// Response type for an OpenID ID token request.
#[derive(Debug, Deserialize)]
struct OpenIdTokenResponse {
    pub id_token: String,
    pub expires_in: u32,
}

/// Error response for OpenID requests.
#[derive(Debug, Deserialize)]
struct OpenIdErrorResponse {
    pub error: String,
}

/// Construct an `HttpRequest` for an OpenID user info request.
pub fn build_user_info_request(access_token: &AccessToken) -> TokenProviderResult<HttpRequest> {
    HttpRequestBuilder::new(USER_INFO_URI.as_str(), "GET")
        .with_header("Authorization", format!("Bearer {}", access_token.0))
        .finish()
}

/// Construct an `HttpRequest` to request an OpenID ID token.
fn build_id_token_request(
    refresh_token: RefreshToken,
    audience: Option<String>,
) -> TokenProviderResult<HttpRequest> {
    // OpenID standard dictates that id_token is returned as part of an Oauth
    // access token response.  Thus, the request is really just an Oauth request.
    oauth::build_request_with_refresh_token(refresh_token, vec![], audience)
}

/// Parse an OpenID user info response.
pub fn parse_user_info_response(
    response_body: Option<String>,
    status_code: StatusCode,
) -> TokenProviderResult<OpenIdUserInfoResponse> {
    match (response_body.as_ref(), status_code) {
        (Some(response), StatusCode::OK) => {
            serde_json::from_str::<OpenIdUserInfoResponse>(&response)
                .token_provider_error(ApiError::Server)
        }
        (Some(response), status) if status.is_client_error() => {
            let error_response = from_str::<OpenIdErrorResponse>(&response)
                .token_provider_error(ApiError::Server)?;
            warn!("Got unexpected error code for OpenId user info: {}", error_response.error);
            Err(TokenProviderError::new(ApiError::Server))
        }
        _ => Err(TokenProviderError::new(ApiError::Server)),
    }
}

/// Parse an OpenID ID token response.
fn parse_id_token_response(
    response_body: Option<String>,
    status_code: StatusCode,
) -> TokenProviderResult<(IdToken, Duration)> {
    match (response_body.as_ref(), status_code) {
        (Some(response), StatusCode::OK) => {
            let OpenIdTokenResponse { id_token, expires_in } =
                serde_json::from_str::<OpenIdTokenResponse>(&response)
                    .token_provider_error(ApiError::Server)?;
            Ok((IdToken(id_token), Duration::from_seconds(expires_in as i64)))
        }
        (Some(response), status) if status.is_client_error() => {
            let error_response = from_str::<OpenIdErrorResponse>(&response)
                .token_provider_error(ApiError::Server)?;
            warn!("Got unexpected error code while retrieving ID token: {}", error_response.error);
            Err(TokenProviderError::new(ApiError::Server))
        }
        _ => Err(TokenProviderError::new(ApiError::Server)),
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::http::mock::TestHttpClient;
    use crate::time::mock::{FixedClock, TEST_CURRENT_TIME};
    use fidl::endpoints::create_proxy_and_stream;
    use fidl_fuchsia_identity_external::{OauthOpenIdConnectMarker, OauthOpenIdConnectProxy};
    use fidl_fuchsia_identity_tokens::{OauthAccessToken, OauthRefreshToken};
    use fuchsia_async as fasync;
    use fuchsia_zircon::Duration;
    use futures::future::join;
    use hyper::StatusCode;

    async fn run_proxy_test<Fn, Fut>(
        test_object: OauthOpenIdConnect<TestHttpClient, FixedClock>,
        test_fn: Fn,
    ) where
        Fn: FnOnce(OauthOpenIdConnectProxy) -> Fut,
        Fut: Future<Output = Result<(), fidl::Error>>,
    {
        let (proxy, stream) = create_proxy_and_stream::<OauthOpenIdConnectMarker>().unwrap();
        let server_fut = test_object.handle_requests_from_stream(stream);
        let test_fut = test_fn(proxy);
        let (test_res, server_res) = join(test_fut, server_fut).await;
        assert!(test_res.is_ok());
        assert!(server_res.is_ok());
    }

    fn create_refresh_token(content: &str) -> OauthRefreshToken {
        OauthRefreshToken {
            content: Some(content.to_string()),
            account_id: None,
            ..OauthRefreshToken::EMPTY
        }
    }

    fn create_access_token(content: &str) -> OauthAccessToken {
        OauthAccessToken {
            content: Some(content.to_string()),
            expiry_time: None,
            ..OauthAccessToken::EMPTY
        }
    }

    #[fasync::run_until_stalled(test)]
    async fn test_get_id_token_success() {
        let http_result = "{\"id_token\": \"test-id-token\", \"expires_in\": 3600}";
        let mock_http = TestHttpClient::with_response(Some(http_result), StatusCode::OK);
        let test_object = OauthOpenIdConnect::new(mock_http);

        run_proxy_test(test_object, |proxy| async move {
            let id_token = proxy
                .get_id_token_from_refresh_token(OpenIdTokenFromOauthRefreshTokenRequest {
                    refresh_token: Some(create_refresh_token("refresh_token")),
                    audiences: None,
                    ..OpenIdTokenFromOauthRefreshTokenRequest::EMPTY
                })
                .await?
                .unwrap();

            assert_eq!(id_token.content, Some("test-id-token".to_string()),);
            assert_eq!(
                id_token.expiry_time.unwrap(),
                (TEST_CURRENT_TIME.clone() + Duration::from_seconds(3600)).into_nanos()
            );
            Ok(())
        })
        .await;

        // An empty vector for audiences is also accepted as default audience.
        let http_result = "{\"id_token\": \"test-id-token\", \"expires_in\": 3600}";
        let mock_http = TestHttpClient::with_response(Some(http_result), StatusCode::OK);
        let test_object = OauthOpenIdConnect::new(mock_http);

        run_proxy_test(test_object, |proxy| async move {
            let id_token = proxy
                .get_id_token_from_refresh_token(OpenIdTokenFromOauthRefreshTokenRequest {
                    refresh_token: Some(create_refresh_token("refresh_token")),
                    audiences: Some(vec![]),
                    ..OpenIdTokenFromOauthRefreshTokenRequest::EMPTY
                })
                .await?
                .unwrap();

            assert_eq!(id_token.content, Some("test-id-token".to_string()),);
            assert_eq!(
                id_token.expiry_time.unwrap(),
                (TEST_CURRENT_TIME.clone() + Duration::from_seconds(3600)).into_nanos()
            );
            Ok(())
        })
        .await;
    }

    #[fasync::run_until_stalled(test)]
    async fn test_get_id_token_failures() {
        // Invalid request
        let mock_http = TestHttpClient::with_error(ApiError::Internal);
        let test_object = OauthOpenIdConnect::new(mock_http);
        run_proxy_test(test_object, |proxy| async move {
            let request_result = proxy
                .get_id_token_from_refresh_token(OpenIdTokenFromOauthRefreshTokenRequest {
                    refresh_token: Some(create_refresh_token("refresh_token")),
                    audiences: Some(vec!["".to_string()]),
                    ..OpenIdTokenFromOauthRefreshTokenRequest::EMPTY
                })
                .await?;
            assert_eq!(request_result, Err(ApiError::InvalidRequest));
            Ok(())
        })
        .await;

        // Error response
        let http_result = "{\"error\": \"invalid_client\"}";
        let mock_http = TestHttpClient::with_response(Some(http_result), StatusCode::BAD_REQUEST);
        let test_object = OauthOpenIdConnect::new(mock_http);
        run_proxy_test(test_object, |proxy| async move {
            let request_result = proxy
                .get_id_token_from_refresh_token(OpenIdTokenFromOauthRefreshTokenRequest {
                    refresh_token: Some(create_refresh_token("refresh_token")),
                    audiences: None,
                    ..OpenIdTokenFromOauthRefreshTokenRequest::EMPTY
                })
                .await?;
            assert_eq!(request_result, Err(ApiError::Server));
            Ok(())
        })
        .await;

        // Network error
        let mock_http = TestHttpClient::with_error(ApiError::Network);
        let test_object = OauthOpenIdConnect::new(mock_http);
        run_proxy_test(test_object, |proxy| async move {
            let request_result = proxy
                .get_id_token_from_refresh_token(OpenIdTokenFromOauthRefreshTokenRequest {
                    refresh_token: Some(create_refresh_token("refresh_token")),
                    audiences: None,
                    ..OpenIdTokenFromOauthRefreshTokenRequest::EMPTY
                })
                .await?;
            assert_eq!(request_result, Err(ApiError::Network));
            Ok(())
        })
        .await;
    }

    #[fasync::run_until_stalled(test)]
    async fn test_get_user_info_success() {
        let http_response =
            "{\"sub\": \"test-id\", \"name\": \"Bill\", \"profile\": \"profile-url\", \
             \"picture\": \"picture-url\", \"email\": \"bill@test.com\"}";
        let mock_http = TestHttpClient::with_response(Some(http_response), StatusCode::OK);
        let test_object = OauthOpenIdConnect::new(mock_http);
        run_proxy_test(test_object, |proxy| async move {
            let user_info = proxy
                .get_user_info_from_access_token(OpenIdUserInfoFromOauthAccessTokenRequest {
                    access_token: Some(create_access_token("access_token")),
                    ..OpenIdUserInfoFromOauthAccessTokenRequest::EMPTY
                })
                .await?
                .unwrap();
            assert_eq!(
                user_info,
                OpenIdUserInfo {
                    subject: Some("test-id".to_string()),
                    name: Some("Bill".to_string()),
                    email: Some("bill@test.com".to_string()),
                    picture: Some("picture-url".to_string()),
                    ..OpenIdUserInfo::EMPTY
                }
            );
            Ok(())
        })
        .await;
    }

    #[fasync::run_until_stalled(test)]
    async fn test_get_user_info_failures() {
        // Invalid request
        let mock_http = TestHttpClient::with_error(ApiError::Internal);
        let test_object = OauthOpenIdConnect::new(mock_http);
        run_proxy_test(test_object, |proxy| async move {
            let request_result = proxy
                .get_user_info_from_access_token(OpenIdUserInfoFromOauthAccessTokenRequest {
                    access_token: Some(create_access_token("")),
                    ..OpenIdUserInfoFromOauthAccessTokenRequest::EMPTY
                })
                .await?;
            assert_eq!(request_result, Err(ApiError::InvalidRequest));
            Ok(())
        })
        .await;

        // Error response
        let mock_http = TestHttpClient::with_response(None, StatusCode::INTERNAL_SERVER_ERROR);
        let test_object = OauthOpenIdConnect::new(mock_http);
        run_proxy_test(test_object, |proxy| async move {
            let request_result = proxy
                .get_user_info_from_access_token(OpenIdUserInfoFromOauthAccessTokenRequest {
                    access_token: Some(create_access_token("access_token")),
                    ..OpenIdUserInfoFromOauthAccessTokenRequest::EMPTY
                })
                .await?;
            assert_eq!(request_result, Err(ApiError::Server));
            Ok(())
        })
        .await;

        // Network error
        let mock_http = TestHttpClient::with_error(ApiError::Network);
        let test_object = OauthOpenIdConnect::new(mock_http);
        run_proxy_test(test_object, |proxy| async move {
            let request_result = proxy
                .get_user_info_from_access_token(OpenIdUserInfoFromOauthAccessTokenRequest {
                    access_token: Some(create_access_token("access_token")),
                    ..OpenIdUserInfoFromOauthAccessTokenRequest::EMPTY
                })
                .await?;
            assert_eq!(request_result, Err(ApiError::Network));
            Ok(())
        })
        .await;
    }

    #[test]
    fn test_parse_user_info_success() {
        // All optional arguments returned
        let http_result = String::from(
            "{\"sub\": \"id-123\", \"name\": \"Amanda\", \"profile\": \"profile-url\", \
             \"picture\": \"picture-url\", \"email\": \"id-123@example.com\"}",
        );
        let user_info_response =
            parse_user_info_response(Some(http_result), StatusCode::OK).unwrap();
        assert_eq!(
            user_info_response,
            OpenIdUserInfoResponse {
                sub: String::from("id-123"),
                name: Some(String::from("Amanda")),
                email: Some(String::from("id-123@example.com")),
                picture: Some(String::from("picture-url")),
            }
        );

        // Only ID provided
        let http_result = String::from("{\"sub\": \"id-321\"}");
        let user_info_response =
            parse_user_info_response(Some(http_result), StatusCode::OK).unwrap();
        assert_eq!(
            user_info_response,
            OpenIdUserInfoResponse {
                sub: String::from("id-321"),
                name: None,
                email: None,
                picture: None,
            }
        );
    }

    #[test]
    fn test_parse_user_info_failures() {
        // Bad token case
        let invalid_http_result = String::from("{\"error\": \"invalid_token\"}");
        let result = parse_user_info_response(Some(invalid_http_result), StatusCode::UNAUTHORIZED);
        assert_eq!(result.unwrap_err().api_error, ApiError::Server);

        // Server error case
        let result = parse_user_info_response(None, StatusCode::INTERNAL_SERVER_ERROR);
        assert_eq!(result.unwrap_err().api_error, ApiError::Server);

        // Malformed response case
        let invalid_http_result = String::from("\\\\malformed\\\\");
        let result = parse_user_info_response(Some(invalid_http_result), StatusCode::OK);
        assert_eq!(result.unwrap_err().api_error, ApiError::Server);
    }

    #[test]
    fn test_parse_id_token_response_success() {
        let http_result = "{\"id_token\": \"test-id-token\", \"expires_in\": 3600}".to_string();
        let (id_token, expires_in) =
            parse_id_token_response(Some(http_result), StatusCode::OK).unwrap();
        assert_eq!(id_token, IdToken("test-id-token".to_string()));
        assert_eq!(expires_in, Duration::from_seconds(3600));
    }

    #[test]
    fn test_parse_id_token_response_failures() {
        // Bad token case
        let invalid_http_result = "{\"error\": \"invalid_token\"}".to_string();
        let result = parse_id_token_response(Some(invalid_http_result), StatusCode::UNAUTHORIZED);
        assert_eq!(result.unwrap_err().api_error, ApiError::Server);

        // Server error case
        let result = parse_id_token_response(None, StatusCode::INTERNAL_SERVER_ERROR);
        assert_eq!(result.unwrap_err().api_error, ApiError::Server);

        // Malformed response case
        let invalid_http_result = "\\\\malformed\\\\".to_string();
        let result = parse_id_token_response(Some(invalid_http_result), StatusCode::OK);
        assert_eq!(result.unwrap_err().api_error, ApiError::Server);
    }
}
