use actix_web::{HttpResponse, web};

use crate::{
    AppState,
    error::{Error, Result},
};

#[derive(serde::Deserialize)]
pub struct Params {
    repo_id: String,
    file: String,
}

pub async fn proxy_file(
    app_state: web::Data<AppState>,
    path: web::Path<Params>,
) -> Result<HttpResponse> {
    let repo = app_state
        .user
        .get_approved_repository(&path.repo_id)
        .await?
        .ok_or(Error::NotFound)?;
    let token = app_state.user.get_access_token(&repo.owner_id).await?;

    let url = format!(
        "https://raw.githubusercontent.com/{}/HEAD/dist/{}",
        repo.full_name, path.file
    );

    let response = app_state
        .reqwest_client
        .get(&url)
        .bearer_auth(token)
        .send()
        .await?;
    response
        .error_for_status_ref()
        .map_err(|_| crate::error::Error::NotFound)?;

    let stream = response.bytes_stream();
    let mime = mime_guess::from_path(&path.file)
        .first_or_octet_stream()
        .to_string();

    Ok(HttpResponse::Ok()
        .content_type(mime)
        .insert_header(("Cache-Control", "public, max-age=3600"))
        .streaming(stream))
}
