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

//! Provide Google Cloud Storage (GCS) access.

use {
    anyhow::{bail, Context, Result},
    async_lock::Mutex,
    fuchsia_hyper::HttpsClient,
    http::{request, StatusCode},
    hyper::{Body, Method, Request, Response},
    once_cell::sync::OnceCell,
    regex::Regex,
    serde::{Deserialize, Serialize},
    serde_json,
    std::{
        fmt, fs,
        io::{self, BufRead, BufReader, Read, Write},
        path::Path,
        string::String,
    },
    thiserror::Error,
    url::{form_urlencoded, Url},
};

/// For a web site, a client secret is kept locked away in a secure server. This
/// is not a web site and the value is needed, so a non-secret "secret" is used.
///
/// These values (and the quote following) are taken form
/// https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/c6a2ee693093926868170f678d8d290bf0de0c15/third_party/gsutil/oauth2_plugin/oauth2_helper.py
/// and
/// https://chromium.googlesource.com/catapult/+/2c541cdf008959bc9813c641cc4ecd0194979486/third_party/gsutil/gslib/utils/system_util.py#177
///
/// "Google OAuth2 clients always have a secret, even if the client is an
/// installed application/utility such as gsutil.  Of course, in such cases the
/// "secret" is actually publicly known; security depends entirely on the
/// secrecy of refresh tokens, which effectively become bearer tokens."
const GSUTIL_CLIENT_ID: &str = "909320924072.apps.googleusercontent.com";
const GSUTIL_CLIENT_SECRET: &str = "p3RlpR10xMFh9ZXBS/ZNLYUu";

const APPROVE_AUTH_CODE_URL: &str = "\
        https://accounts.google.com/o/oauth2/auth?\
scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform\
&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob\
&response_type=code\
&access_type=offline\
&client_id=";

/// Base URL for JSON API access.
const API_BASE: &str = "https://www.googleapis.com/storage/v1";

/// Base URL for reading (blob) objects.
const STORAGE_BASE: &str = "https://storage.googleapis.com";

/// URL used to exchange an auth_code for a refresh_token.
const EXCHANGE_AUTH_CODE_URL: &str = "https://oauth2.googleapis.com/token";

/// URL used for gaining a new access token.
///
/// See RefreshTokenRequest, OauthTokenResponse.
const OAUTH_REFRESH_TOKEN_ENDPOINT: &str = "https://www.googleapis.com/oauth2/v3/token";

/// Errors specific to this lib, some may be addressed by the caller.
#[derive(Error, Debug)]
pub enum GcsError {
    /// The refresh token is no longer valid (e.g. expired or revoked).
    /// Do something similar to `gsutil config` or auth_code_url() to generate a
    /// new refresh token and try again.
    #[error("GCS refresh token is invalid. Please generate a new GCS OAUTH2 refresh token.")]
    NeedNewRefreshToken,

    /// The access token is no longer valid (e.g. expired or revoked). Access
    /// tokens are short lived and don't require user interaction to renew.
    /// Refresh the access token and try the action again.
    #[error("GCS access token is invalid. This should be handled. Report as a bug.")]
    NeedNewAccessToken,

    /// GCS returned an empty response for the request.
    #[error("The requested GCS bucket + path contains no data (not found): {0}, {1}.")]
    NotFound(String, String),

    /// The authorization code is empty string (or None). Likely a mistake in
    /// the calling application (e.g. calling new_with_code() with an empty
    /// string).
    #[error("Empty authorization code passed to GCS. Report as a bug.")]
    MissingAuthCode,

    /// Likely a mistake in the calling application.
    #[error("A GCS refresh token is required to gain a new access token. Report as a bug.")]
    MissingRefreshToken,

    /// May be a network issue. Consider informing the user and offer to retry.
    #[error(
        "Unable to refresh GCS access token: HTTP {0}. Check network connection and try again."
    )]
    RefreshAccessError(http::StatusCode),

    /// May be a network issue. Consider informing the user and offer to retry.
    #[error("GCS HttpResponseError: {0}. Check network connection and try again.")]
    HttpResponseError(http::StatusCode),

    /// May be a network issue. Consider informing the user and offer to retry.
    #[error("GCS HttpError: {0}. Check network connection and try again.")]
    HttpError(#[from] http::Error),

    /// May be a network issue. Consider informing the user and offer to retry.
    #[error("GCS HyperError: {0}. Check network connection and try again.")]
    HyperError(#[from] hyper::Error),

    /// Possible in-transit corruption, but more likely the GCS protocol
    /// changed. May need to update GCS lib.
    #[error("GCS SerdeError: {0}. Report as a bug.")]
    SerdeError(#[from] serde_json::Error),
}

/// POST body to [`OAUTH_REFRESH_TOKEN_ENDPOINT`].
#[derive(Serialize)]
struct RefreshTokenRequest<'a> {
    /// A value provided by GCS for fetching tokens.
    client_id: &'a str,

    /// A (normally secret) value provided by GCS for fetching tokens.
    client_secret: &'a str,

    /// A long lasting secret token used to attain a new `access_token`.
    refresh_token: &'a str,

    /// Will be "refresh_token" for a refresh token.
    grant_type: &'a str,
}

/// Response body from [`OAUTH_REFRESH_TOKEN_ENDPOINT`].
/// 'expires_in' is intentionally omitted.
#[derive(Deserialize)]
struct OauthTokenResponse {
    /// A limited time (see `expires_in`) token used in an Authorization header.
    access_token: String,
}

/// POST body to [`EXCHANGE_AUTH_CODE_URL`].
#[derive(Serialize)]
struct ExchangeAuthCodeRequest<'a> {
    /// A value provided by GCS for fetching tokens.
    client_id: &'a str,

    /// A (normally secret) value provided by GCS for fetching tokens.
    client_secret: &'a str,

    /// A short lived authorization code used to attain an initial
    /// `refresh_token` and `access_token`.
    code: &'a str,

    /// Will be "authorization_code" for a authorization code.
    grant_type: &'a str,

    /// For our use (a non-web program), always "urn:ietf:wg:oauth:2.0:oob"
    redirect_uri: &'a str,
}

/// Response body from [`EXCHANGE_AUTH_CODE_URL`].
/// 'expires_in' is intentionally omitted.
#[derive(Deserialize)]
struct ExchangeAuthCodeResponse {
    /// A limited time (see `expires_in`) token used in an Authorization header.
    access_token: Option<String>,

    /// A long lasting secret token. This value is a user secret and must not be
    /// misused (such as by logging). Suitable for storing in a local file and
    /// reusing later.
    refresh_token: String,
}

/// Response from the `/b/<bucket>/o` object listing API.
#[derive(Debug, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct ListResponse {
    /// Continuation token; only present when there is more data.
    next_page_token: Option<String>,

    /// List of objects, sorted by name.
    #[serde(default)]
    items: Vec<ListResponseItem>,
}

#[derive(Debug, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct ListResponseItem {
    /// GCS object name.
    name: String,
}

/// User credentials for use with GCS.
///
/// Specifically to:
/// - api_base: https://www.googleapis.com/storage/v1
/// - storage_base: https://storage.googleapis.com
pub struct TokenStore {
    /// Base URL for JSON API access.
    api_base: Url,

    /// Base URL for reading (blob) objects.
    storage_base: Url,

    /// A long lasting secret token used to attain a new `access_token`. This
    /// value is a user secret and must not be misused (such as by logging).
    refresh_token: Option<String>,

    /// A limited time token used in an Authorization header.
    ///
    /// Only valid if `Instant::now() < expired()`, though it's better to allow
    /// some extra time (e.g. maybe 30 seconds).
    access_token: Mutex<String>,
}

impl TokenStore {
    /// Only allow access to public GCS data.
    pub fn new_without_auth() -> Self {
        Self {
            api_base: Url::parse(API_BASE).expect("parse API_BASE"),
            storage_base: Url::parse(STORAGE_BASE).expect("parse STORAGE_BASE"),
            refresh_token: None,
            access_token: Mutex::new("".to_string()),
        }
    }

    /// Allow access to public and private (auth-required) GCS data.
    ///
    /// The `refresh_token` must not be an empty string (this will generate an
    /// Err Result.
    ///
    /// The `access_token` is not required, but if it happens to be available,
    /// i.e. if a code exchange was just done, it avoids an extra round-trip to
    /// provide it here.
    pub fn new_with_auth<T>(refresh_token: String, access_token: T) -> Result<Self, GcsError>
    where
        T: Into<Option<String>>,
    {
        if refresh_token.is_empty() {
            return Err(GcsError::MissingRefreshToken);
        }
        let access_token = Mutex::new(access_token.into().unwrap_or("".to_string()));
        Ok(Self {
            api_base: Url::parse(API_BASE).expect("parse API_BASE"),
            storage_base: Url::parse(STORAGE_BASE).expect("parse STORAGE_BASE"),
            refresh_token: Some(refresh_token),
            access_token,
        })
    }

    /// Allow access to public and private GCS data.
    ///
    /// The `https_client` will be used to exchange the auth code for a refresh
    /// token.
    /// The `auth_code` must not be an empty string (this will generate an Err
    /// Result.
    pub async fn new_with_code(
        https_client: &HttpsClient,
        auth_code: &str,
    ) -> Result<Self, GcsError> {
        if auth_code.is_empty() {
            return Err(GcsError::MissingAuthCode);
        }
        // Add POST parameters to exchange the auth_code for a refresh_token
        // and possibly an access_token.
        let body = form_urlencoded::Serializer::new(String::new())
            .append_pair("code", auth_code)
            .append_pair("redirect_uri", "urn:ietf:wg:oauth:2.0:oob")
            .append_pair("client_id", GSUTIL_CLIENT_ID)
            .append_pair("client_secret", GSUTIL_CLIENT_SECRET)
            .append_pair("grant_type", "authorization_code")
            .finish();
        // Build the request and send it.
        let req = Request::builder()
            .method(Method::POST)
            .header("Content-Type", "application/x-www-form-urlencoded")
            .uri(EXCHANGE_AUTH_CODE_URL)
            .body(Body::from(body))?;
        let res = https_client.request(req).await?;

        // If the response was successful, extract the new tokens.
        if res.status().is_success() {
            let bytes = hyper::body::to_bytes(res.into_body()).await?;
            let info: ExchangeAuthCodeResponse = serde_json::from_slice(&bytes)?;
            let access_token = Mutex::new(info.access_token.unwrap_or("".to_string()));
            Ok(Self {
                api_base: Url::parse(API_BASE).expect("parse API_BASE"),
                storage_base: Url::parse(STORAGE_BASE).expect("parse STORAGE_BASE"),
                refresh_token: Some(info.refresh_token),
                access_token,
            })
        } else {
            return Err(GcsError::RefreshAccessError(res.status()));
        }
    }

    pub fn refresh_token(&self) -> Option<String> {
        self.refresh_token.to_owned()
    }

    /// Create localhost base URLs and fake credentials for testing.
    #[cfg(test)]
    fn local_fake(refresh_token: Option<String>) -> Self {
        let api_base = Url::parse("http://localhost:9000").expect("api_base");
        let storage_base = Url::parse("http://localhost:9001").expect("storage_base");
        Self { api_base, storage_base, refresh_token, access_token: Mutex::new("".to_string()) }
    }

    /// Apply Authorization header, if available.
    ///
    /// If no access_token is set, no changes are made to the builder.
    async fn authorize(&self, builder: request::Builder) -> Result<request::Builder> {
        if self.refresh_token.is_none() {
            return Ok(builder);
        }
        let access_token = self.access_token.lock().await;
        Ok(builder.header("Authorization", format!("Bearer {}", access_token)))
    }

    /// Use the refresh token to get a new access token.
    async fn refresh_access_token(&self, https_client: &HttpsClient) -> Result<(), GcsError> {
        match &self.refresh_token {
            Some(refresh_token) => {
                let req_body = RefreshTokenRequest {
                    client_id: GSUTIL_CLIENT_ID,
                    client_secret: GSUTIL_CLIENT_SECRET,
                    refresh_token: refresh_token,
                    grant_type: "refresh_token",
                };
                let body = serde_json::to_vec(&req_body)?;
                let req = Request::builder()
                    .method(Method::POST)
                    .uri(OAUTH_REFRESH_TOKEN_ENDPOINT)
                    .body(Body::from(body))?;

                let res = https_client.request(req).await?;

                if res.status().is_success() {
                    let bytes = hyper::body::to_bytes(res.into_body()).await?;
                    let info: OauthTokenResponse = serde_json::from_slice(&bytes)?;
                    let mut access_token = self.access_token.lock().await;
                    *access_token = info.access_token;
                    Ok(())
                } else {
                    match res.status() {
                        StatusCode::BAD_REQUEST => return Err(GcsError::NeedNewRefreshToken),
                        _ => return Err(GcsError::HttpResponseError(res.status())),
                    }
                }
            }
            None => return Err(GcsError::MissingRefreshToken),
        }
    }

    /// Reads content of a stored object (blob) from GCS.
    ///
    /// A leading slash "/" on `object` will be ignored.
    pub(crate) async fn download(
        &self,
        https_client: &HttpsClient,
        bucket: &str,
        object: &str,
    ) -> Result<Response<Body>> {
        // If the bucket and object are from a gs:// URL, the object may have a
        // undesirable leading slash. Trim it if present.
        let object = if object.starts_with('/') { &object[1..] } else { object };

        let res = self.attempt_download(https_client, bucket, object).await?;
        Ok(match res.status() {
            StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED => {
                match &self.refresh_token {
                    Some(_) => {
                        // Refresh the access token and make one extra try.
                        self.refresh_access_token(&https_client).await?;
                        self.attempt_download(https_client, bucket, object).await?
                    }
                    None => {
                        // With no refresh token, there's no option to retry.
                        res
                    }
                }
            }
            _ => res,
        })
    }

    /// Make one attempt to read content of a stored object (blob) from GCS
    /// without considering redirects or retries.
    ///
    /// Callers are expected to handle errors and call attempt_download() again
    /// as desired (e.g. follow redirects).
    async fn attempt_download(
        &self,
        https_client: &HttpsClient,
        bucket: &str,
        object: &str,
    ) -> Result<Response<Body>> {
        let url = self.storage_base.join(&format!("{}/{}", bucket, object))?;
        self.send_request(https_client, url).await
    }

    /// Make one attempt to request data from GCS.
    ///
    /// Callers are expected to handle errors and call attempt_download() again
    /// as desired (e.g. follow redirects).
    async fn send_request(&self, https_client: &HttpsClient, url: Url) -> Result<Response<Body>> {
        let req = Request::builder().method(Method::GET).uri(url.into_string());
        let req = self.authorize(req).await?;
        let req = req.body(Body::from(""))?;

        let res = https_client.request(req).await?;
        Ok(res)
    }

    /// List objects from GCS in `bucket` with matching `prefix`.
    ///
    /// A leading slash "/" on `prefix` will be ignored.
    pub async fn list(
        &self,
        https_client: &HttpsClient,
        bucket: &str,
        prefix: &str,
    ) -> Result<Vec<String>> {
        Ok(match self.attempt_list(https_client, bucket, prefix).await {
            Err(e) => {
                match e.downcast_ref::<GcsError>() {
                    Some(GcsError::NeedNewAccessToken) => {
                        match &self.refresh_token {
                            Some(_) => {
                                // Refresh the access token and make one extra try.
                                self.refresh_access_token(&https_client).await?;
                                self.attempt_list(https_client, bucket, prefix).await?
                            }
                            None => {
                                // With no refresh token, there's no option to retry.
                                bail!(
                                    "Access to gs://{}/{} requires authorization. Error {:?}",
                                    bucket,
                                    prefix,
                                    e
                                );
                            }
                        }
                    }
                    Some(_) | None => {
                        bail!("Unable to list GCS data. Error {:?}", e);
                    }
                }
            }
            Ok(value) => value,
        })
    }

    /// Make one attempt to list objects from GCS.
    async fn attempt_list(
        &self,
        https_client: &HttpsClient,
        bucket: &str,
        prefix: &str,
    ) -> Result<Vec<String>> {
        // If the bucket and prefix are from a gs:// URL, the prefix may have a
        // undesirable leading slash. Trim it if present.
        let prefix = if prefix.starts_with('/') { &prefix[1..] } else { prefix };

        let mut base_url = self.api_base.to_owned();
        base_url.path_segments_mut().unwrap().extend(&["b", bucket, "o"]);
        base_url
            .query_pairs_mut()
            .append_pair("prefix", prefix)
            .append_pair("prettyPrint", "false")
            .append_pair("fields", "nextPageToken,items/name");
        let mut results = Vec::new();
        let mut page_token: Option<String> = None;
        loop {
            // Create a new URL for each "page" of results.
            let mut url = base_url.clone();
            if let Some(t) = page_token {
                url.query_pairs_mut().append_pair("pageToken", t.as_str());
            }
            let res = self.send_request(https_client, url).await?;
            match res.status() {
                StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED => {
                    bail!(GcsError::NeedNewAccessToken);
                }
                StatusCode::OK => {
                    let bytes = hyper::body::to_bytes(res.into_body()).await?;
                    let info: ListResponse = serde_json::from_slice(&bytes)?;
                    results.extend(info.items.into_iter().map(|i| i.name));
                    if info.next_page_token.is_none() {
                        break;
                    }
                    page_token = info.next_page_token;
                }
                _ => {
                    bail!("Failed to list {:?} {:?}", base_url, res);
                }
            }
        }
        if results.is_empty() {
            bail!(GcsError::NotFound(bucket.to_string(), prefix.to_string()));
        }
        Ok(results)
    }
}

impl fmt::Debug for TokenStore {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("TokenStore")
            .field("api_base", &self.api_base)
            .field("storage_base", &self.storage_base)
            .field("refresh_token", &self.refresh_token.as_ref().map(|_| ".."))
            .field("access_token", &"..")
            .finish()
    }
}

/// URL which guides the user to an authorization code.
///
/// Expected flow:
/// - Request that the user open a browser to this location
/// - authorize and grant permission to this program to use GCS
/// - user, copy-pastes the auth code the web page provides back to this program
/// - create a TokenStore with TokenStore::new_with_code(pasted_string)
pub fn auth_code_url() -> String {
    APPROVE_AUTH_CODE_URL.to_string() + GSUTIL_CLIENT_ID
}

/// Convert an authorization code to a refresh token.
pub async fn auth_code_to_refresh(auth_code: &str) -> Result<String> {
    use fuchsia_hyper::new_https_client;
    let token_store = TokenStore::new_with_code(&new_https_client(), auth_code).await?;
    match token_store.refresh_token() {
        Some(s) => Ok(s.to_string()),
        None => bail!("auth_code_to_refresh failed"),
    }
}

/// Ask the user to visit a URL and copy-paste the auth code provided.
///
/// A helper wrapper around get_auth_code_with() using stdin/stdout.
///
/// E.g. to get a Refresh Token
/// ```
///    let auth_code = get_auth_code()?;
///    let refresh_token = auth_code_to_refresh(&auth_code).await?;
/// ```
pub fn get_auth_code() -> Result<String> {
    let stdout = io::stdout();
    let mut output = stdout.lock();
    let stdin = io::stdin();
    let mut input = stdin.lock();
    get_auth_code_with(&mut output, &mut input)
}

/// Ask the user to visit a URL and copy-paste the authorization code provided.
///
/// Consider using `get_auth_code()` for operation with stdin/stdout.
///
/// For a GUI, consider creating a separate (custom) function to ask the user to
/// follow the web flow to get a authorization code (tip: use `auth_code_url()`
/// to get the URL).
pub fn get_auth_code_with<W, R>(writer: &mut W, reader: &mut R) -> Result<String>
where
    W: Write,
    R: Read,
{
    writeln!(
        writer,
        "Please visit this site. Proceed through the web flow to allow access \
        and copy the authentication code:\
        \n\n{}\n\nPaste the code (from the web page) here\
        \nand press return: ",
        auth_code_url(),
    )?;
    writer.flush().expect("flush auth code prompt");
    let mut auth_code = String::new();
    let mut buf_reader = BufReader::new(reader);
    buf_reader.read_line(&mut auth_code).expect("Need an auth_code.");
    Ok(auth_code.trim().to_string())
}

/// Fetch an existing refresh token from a .boto (gsutil) configuration file.
///
/// Tip, the `boto_path` is commonly "~/.boto". E.g.
/// ```
/// use home::home_dir;
/// let boto_path = Path::new(&home_dir().expect("home dir")).join(".boto");
/// ```
///
/// TODO(fxbug.dev/82014): Using an ffx specific token will be preferred once
/// that feature is created. For the near term, an existing gsutil token is
/// workable.
///
/// Alert: The refresh token is considered a private secret for the user. Do
///        not print the token to a log or otherwise disclose it.
pub fn read_boto_refresh_token<P: AsRef<Path>>(boto_path: P) -> Result<Option<String>> {
    // Read the file at `boto_path` to retrieve a value from a line resembling
    // "gs_oauth2_refresh_token = <string_of_chars>".
    static GS_REFRESH_TOKEN_RE: OnceCell<Regex> = OnceCell::new();
    let re = GS_REFRESH_TOKEN_RE
        .get_or_init(|| Regex::new(r#"\n\s*gs_oauth2_refresh_token\s*=\s*(\S+)"#).expect("regex"));
    let data = fs::read_to_string(boto_path.as_ref())?;
    let refresh_token = match re.captures(&data) {
        Some(found) => Some(found.get(1).expect("found at least one").as_str().to_string()),
        None => None,
    };
    Ok(refresh_token)
}

/// Overwrite the 'gs_oauth2_refresh_token' in the file at `boto_path`.
///
/// TODO(fxbug.dev/82014): Using an ffx specific token will be preferred once
/// that feature is created. For the near term, an existing gsutil token is
/// workable.
///
/// Alert: The refresh token is considered a private secret for the user. Do
///        not print the token to a log or otherwise disclose it.
pub fn write_boto_refresh_token<P: AsRef<Path>>(boto_path: P, token: &str) -> Result<()> {
    use std::{fs::set_permissions, os::unix::fs::PermissionsExt};
    let boto_path = boto_path.as_ref();
    let data = if !boto_path.is_file() {
        fs::File::create(boto_path).context("Create .boto file")?;
        const USER_READ_WRITE: u32 = 0o600;
        let permissions = std::fs::Permissions::from_mode(USER_READ_WRITE);
        set_permissions(&boto_path, permissions).context("Boto set permissions")?;
        format!(
            "# This file was created by the Fuchsia GCS lib.\
            \n[GSUtil]\
            \ngs_oauth2_refresh_token = {}\
            \ndefault_project_id =\
            \n",
            token
        )
    } else {
        static GS_UPDATE_REFRESH_TOKEN_RE: OnceCell<Regex> = OnceCell::new();
        let re = GS_UPDATE_REFRESH_TOKEN_RE.get_or_init(|| {
            Regex::new(r#"(\n\s*gs_oauth2_refresh_token\s*=\s*)\S*"#).expect("regex")
        });
        let data = fs::read_to_string(boto_path).context("read boto refresh")?;
        re.replace(&data, format!("${{1}}{}", token).as_str()).to_string()
    };
    fs::write(boto_path, data).context("Writing .boto file")?;
    Ok(())
}

#[cfg(test)]
mod test {
    use {super::*, fuchsia_hyper::new_https_client, hyper::StatusCode, tempfile};

    #[test]
    fn test_approve_auth_code_url() {
        // If the GSUTIL_CLIENT_ID is changed, the APPROVE_AUTH_CODE_URL must be
        // updated as well.
        assert_eq!(
            auth_code_url(),
            format!(
                "\
            https://accounts.google.com/o/oauth2/auth?\
            scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform\
            &redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob\
            &response_type=code\
            &access_type=offline\
            &client_id={}",
                GSUTIL_CLIENT_ID
            )
        );
    }

    #[test]
    fn test_get_auth_code_with() {
        let mut output: Vec<u8> = Vec::new();
        let mut input = "fake_auth_code".as_bytes();
        let auth_code = get_auth_code_with(&mut output, &mut input).expect("auth code");
        assert_eq!(auth_code, "fake_auth_code");
    }

    #[should_panic(expected = "Connection refused")]
    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_fake_download() {
        let token_store = TokenStore::local_fake(/*refresh_token=*/ None);
        let bucket = "fake_bucket";
        let object = "fake/object/path.txt";
        token_store.download(&new_https_client(), bucket, object).await.expect("client download");
    }

    // This test is marked "ignore" because it actually downloads from GCS,
    // which isn't good for a CI/GI test. It's here because it's handy to have
    // as a local developer test. Run with `fx test gcs_lib_test -- --ignored`.
    // Note: gsutil config is required.
    #[ignore]
    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_gcs_download_public() {
        let token_store = TokenStore::new_without_auth();
        let bucket = "fuchsia";
        let object = "development/5.20210610.3.1/sdk/linux-amd64/gn.tar.gz";
        let res = token_store
            .download(&new_https_client(), bucket, object)
            .await
            .expect("client download");
        assert_eq!(res.status(), StatusCode::OK);
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_gcs_read_write_refresh_token() {
        let boto_temp = tempfile::TempDir::new().expect("temp dir");
        let boto_path = boto_temp.path().join(".boto");
        assert!(!boto_path.is_file());
        // Test with no .boto file.
        write_boto_refresh_token(&boto_path, "first-token").expect("write token");
        assert!(boto_path.is_file());
        let refresh_token =
            read_boto_refresh_token(&boto_path).expect("boto").expect("first token");
        assert_eq!(refresh_token, "first-token");
        // Test updating existing .boto file.
        write_boto_refresh_token(&boto_path, "second-token").expect("write token");
        let refresh_token =
            read_boto_refresh_token(&boto_path).expect("boto").expect("second token");
        assert_eq!(refresh_token, "second-token");
    }

    // This test is marked "ignore" because it actually downloads from GCS,
    // which isn't good for a CI/GI test. It's here because it's handy to have
    // as a local developer test. Run with `fx test gcs_lib_test -- --ignored`.
    // Note: gsutil config is required.
    #[ignore]
    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_gcs_download_auth() {
        use home::home_dir;
        let boto_path = Path::new(&home_dir().expect("home dir")).join(".boto");
        let refresh_token =
            read_boto_refresh_token(&boto_path).expect("boto file").expect("refresh token");
        let token_store = TokenStore::new_with_auth(refresh_token, /*access_token=*/ None)
            .expect("new with auth");
        let https = new_https_client();
        token_store.refresh_access_token(&https).await.expect("refresh_access_token");
        let bucket = "fuchsia-sdk";
        let object = "development/LATEST_LINUX";
        let res = token_store.download(&https, bucket, object).await.expect("client download");
        assert_eq!(res.status(), StatusCode::OK);
    }
}
