// 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::models::Action, failure::Error, fidl_fuchsia_net_oldhttp as http,
    fuchsia_async as fasync, fuchsia_component as component, fuchsia_syslog::macros::*,
    fuchsia_zircon as zx, futures::io::AsyncReadExt, serde_derive::Deserialize,
};

/// Returns a vec of HttpHeaders used for Discover Cloud API request.
/// Returns error on failure.
///
/// Currently, discovermgr uses the device_name as Auth header.
/// http_headers need "Authorization: ApiKey xxxxxx"
/// for access authorization. Using the device_name as the apikey
/// is a hack and should be removed when we decide to use the
/// logged in user for access authorization.
///
async fn get_discover_cloud_http_headers(
    device_name: &str,
) -> Result<Vec<http::HttpHeader>, Error> {
    let mut http_headers = vec![http::HttpHeader {
        name: "Accept".to_string(),
        value: "application/json".to_string(),
    }];

    http_headers.push(http::HttpHeader {
        name: "Authorization".to_string(),
        value: format!("ApiKey {}", device_name).to_string(),
    });

    Ok(http_headers)
}

/// Fetch the contents of a URL as a string.
///
/// Returns error on failure.
///
/// Connects to the http service, sends a url request, and prints the response.
async fn http_get(url: &str, headers: Vec<http::HttpHeader>) -> Result<String, Error> {
    // Connect to the http service
    let net = component::client::connect_to_service::<http::HttpServiceMarker>()?;

    // Create a UrlLoader instance
    let (loader_proxy, server_end) = fidl::endpoints::create_proxy::<http::UrlLoaderMarker>()?;
    net.create_url_loader(server_end)?;

    // Send the UrlRequest to fetch the webpage
    let mut req = http::UrlRequest {
        url: url.to_string(),
        method: "GET".to_string(),
        headers: Some(headers),
        body: None,
        response_body_buffer_size: 0,
        auto_follow_redirects: true,
        cache_mode: http::CacheMode::Default,
        response_body_mode: http::ResponseBodyMode::Stream,
    };

    let resp = loader_proxy.start(&mut req).await?;
    if let Some(e) = resp.error {
        return Err(failure::err_msg(e.description.unwrap_or("".into())));
    }

    let mut socket = match resp.body.map(|x| *x) {
        Some(http::UrlBody::Stream(s)) => fasync::Socket::from_socket(s)?,
        _ => return Err(Error::from(zx::Status::BAD_STATE)),
    };

    // Copy the socket contents to a String.
    let mut output = vec![];
    socket.read_to_end(&mut output).await?;
    let result = String::from_utf8(output)?;
    fx_log_info!("Returned http bytes {} from {}", result.len(), url);
    Ok(result)
}

// helper to call serde and return the right type of error
fn serde_from_str(json: &str) -> Result<Vec<Action>, Error> {
    serde_json::from_str(json).map_err(|e| Error::from(e))
}

/// Fetch actions from cloud.
///
async fn get_actions_http(url: &str) -> Result<Vec<Action>, Error> {
    let name_provider =
        component::client::connect_to_service::<fidl_fuchsia_device::NameProviderMarker>()?;
    let device_name = name_provider.get_device_name().await?.map_err(zx::Status::from_raw)?;
    let http_headers = get_discover_cloud_http_headers(&device_name).await?;
    // Fetch the body and parse, returning error messages on failure
    http_get(url, http_headers).await
        .or_else(|_| {
            fx_log_err!("Unable to fetch actions from cloud - ({})", url);
            Err(failure::err_msg(format!("Unable to fetch actions from cloud ({})", url)))
        })
        .and_then(|body| serde_from_str(body.as_str()))
        .or_else(|e: Error| {
            fx_log_err!("Unable to parse cloud actions - {:?}", e);
            Err(failure::err_msg(format!("Unable to parse cloud actions - ({:?})", e)))
        })
}

/// Fetch actions from cloud.
pub async fn get_cloud_actions() -> Result<Vec<Action>, Error> {
    // Configuration struct for this module contain the default cloud url
    let config: Config =
        serde_json::from_str(include_str!("../config/cloud_discover.json")).unwrap();
    get_actions_http(&config.url).await
}

/// The URL for cloud_discover is configurable
#[derive(Deserialize, Debug)]
struct Config {
    url: String,
}

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

    #[fasync::run_singlethreaded(test)]
    async fn test_http_get() -> Result<(), Error> {
        // Check for default url, expect an Err()
        assert!(get_cloud_actions().await.is_err());

        // Check for bad url, expect an Err()
        assert!(get_actions_http("http://example.com").await.is_err());

        Ok(())
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_get_discover_cloud_http_headers() -> Result<(), Error> {
        let fake_device_name = "four-word-node-name";
        let response = get_discover_cloud_http_headers(&fake_device_name).await?;
        assert_eq!(
            response,
            vec![
                http::HttpHeader {
                    name: "Accept".to_string(),
                    value: "application/json".to_string(),
                },
                http::HttpHeader {
                    name: "Authorization".to_string(),
                    value: format!("ApiKey {}", fake_device_name).to_string(),
                },
            ]
        );

        Ok(())
    }
}
