use std::error::Error;

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct RegistryTokenResponse {
    token: Option<String>,
    access_token: Option<String>,
    expires_in: u32,
    issued_at: Option<String>,
}

/// get the access token for tags request
pub(crate) async fn get_token(
    namespace: &str,
    repository: &str,
    username: &str,
    password: &str,
) -> Result<String, Box<dyn Error + Send + Sync>> {
    let service = "registry.docker.io";
    let scope = format!("repository:{namespace}/{repository}:pull");
    let auth = format!("https://auth.docker.io/token?service={service}&scope={scope}");
    let client = reqwest::Client::new();
    let response = client
        .get(auth)
        .basic_auth(username, Some(password))
        .send()
        .await?;
    let json: RegistryTokenResponse = response.json().await?;
    Ok(json.token.unwrap())
}
