use std::collections::HashMap;
use crate::api::ApiClient;
const MIN_CHUNK_SIZE: usize = 10_000_000; const MAX_CHUNK_COUNT: usize = 9_000;
pub fn upload_module_input(
api_client: &mut ApiClient,
job_uuid: &str,
job_auth_token: &str,
module_input: &[u8],
) -> crate::Result<()> {
let mut headers = HashMap::new();
headers.insert("job-auth-token".to_string(), job_auth_token.to_string());
let start_response = api_client.start_multipart_upload(
&format!("/jobs/{job_uuid}/storage/input/start_upload/"),
Some(&headers),
)?;
let chunk_size = calculate_chunk_size(module_input.len());
let mut parts = Vec::new();
let mut offset = 0usize;
let mut part_number = 1u32;
while offset < module_input.len() {
let end = std::cmp::min(offset + chunk_size, module_input.len());
let chunk = &module_input[offset..end];
let presigned_url = api_client.get_presigned_upload_url(
&format!("/jobs/{job_uuid}/storage/input/presigned_upload_url/"),
part_number,
&start_response.upload_id,
Some(&headers),
)?;
let etag = api_client.upload_to_presigned_url(&presigned_url, chunk)?;
parts.push(serde_json::json!({
"ETag": etag,
"PartNumber": part_number,
}));
offset = end;
part_number += 1;
}
api_client.complete_multipart_upload(
&format!("/jobs/{job_uuid}/storage/input/complete_upload/"),
&start_response.upload_id,
&parts,
Some(&headers),
)?;
Ok(())
}
fn calculate_chunk_size(total_size: usize) -> usize {
std::cmp::max(MIN_CHUNK_SIZE, total_size / MAX_CHUNK_COUNT)
}