use super::transcode_generator::TranscodeGenerator;
use crate::testing_prelude::*;
use std::sync::Mutex;
#[expect(
clippy::type_complexity,
reason = "type alias would obscure cache structure"
)]
static TRANSCODE_CACHE: LazyLock<
Mutex<HashMap<String, Arc<OnceCell<Result<TranscodeConfig, String>>>>>,
> = LazyLock::new(|| Mutex::new(HashMap::new()));
pub struct TranscodeProvider;
impl TranscodeProvider {
pub async fn get(source: SampleFormat, target: TargetFormat) -> TranscodeConfig {
let album = AlbumProvider::get(source).await;
Self::get_advanced(&album, target).await
}
#[expect(
clippy::panic,
reason = "sample generation is unrecoverable. clear message is rendered"
)]
pub async fn get_advanced(album: &AlbumConfig, target: TargetFormat) -> TranscodeConfig {
let config = TranscodeConfig::new(album.clone(), target);
let key = config.dir_name();
let cell = {
let mut map = TRANSCODE_CACHE
.lock()
.expect("transcode cache mutex should not be poisoned");
Arc::clone(map.entry(key).or_insert_with(|| Arc::new(OnceCell::new())))
};
cell.get_or_init(|| async {
let transcode_dir = config.transcode_dir();
if !is_generated(&transcode_dir) {
TranscodeGenerator::generate_files(&config, &transcode_dir)
.await
.map_err(|e| e.render())?;
mark_generated(&transcode_dir)?;
}
Ok(config)
})
.await
.clone()
.unwrap_or_else(|e| panic!("Transcode generation failed\n{e}"))
}
}
fn is_generated(dir: &Path) -> bool {
dir.join(".generated").exists()
}
fn mark_generated(dir: &Path) -> Result<(), String> {
let path = dir.join(".generated");
File::create(&path).map_err(|e| format!("failed to create {}: {e}", path.display()))?;
Ok(())
}