use async_trait::async_trait;
use serde::Deserialize;
use serde_json::Value;
use tokio::io::AsyncBufRead;
use crate::core::bulk_export::ExportJobId;
use crate::core::bulk_submit::SubmissionId;
use crate::error::StorageResult;
#[derive(Debug, Clone, Deserialize)]
pub struct RemoteFile {
#[serde(rename = "type", default)]
pub resource_type: Option<String>,
pub url: String,
#[serde(default)]
pub count: Option<u64>,
}
#[derive(Debug, Clone, Default, Deserialize)]
pub struct RemoteManifest {
#[serde(rename = "requiresAccessToken", default)]
pub requires_access_token: bool,
#[serde(default)]
pub output: Vec<RemoteFile>,
#[serde(default)]
pub deleted: Vec<RemoteFile>,
}
#[async_trait]
pub trait FileTokenProvider: Send + Sync {
async fn token(&self, oauth_metadata_urls: &[String], scope: &str) -> Option<String>;
}
#[async_trait]
pub trait SubmitInputFetcher: Send + Sync {
async fn fetch_manifest(
&self,
url: &str,
request_headers: &[(String, String)],
oauth_metadata_urls: &[String],
) -> StorageResult<RemoteManifest>;
async fn open_file_stream(
&self,
url: &str,
request_headers: &[(String, String)],
requires_access_token: bool,
oauth_metadata_urls: &[String],
encryption_key: Option<&Value>,
) -> StorageResult<Box<dyn AsyncBufRead + Send + Unpin>>;
}
pub fn submission_output_job_id(id: &SubmissionId) -> ExportJobId {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
let mut hasher = DefaultHasher::new();
id.submitter.hash(&mut hasher);
0u8.hash(&mut hasher); id.submission_id.hash(&mut hasher);
ExportJobId::from_string(format!("submit-{:016x}", hasher.finish()))
}