use crate::job::{BatchJob, BatchOperation};
use crate::operations::{AnalysisType, FileOperation};
use crate::types::{Priority, RetryPolicy};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JobPreset {
pub name: String,
pub description: String,
pub operation: BatchOperation,
pub priority: Priority,
pub retry: RetryPolicy,
pub parameters: HashMap<String, String>,
}
impl JobPreset {
#[must_use]
pub fn create_job(&self, name: String) -> BatchJob {
let mut job = BatchJob::new(name, self.operation.clone());
job.set_priority(self.priority);
job.set_retry_policy(self.retry.clone());
job
}
}
pub struct PresetManager {
presets: HashMap<String, JobPreset>,
}
impl PresetManager {
#[must_use]
pub fn new() -> Self {
let mut manager = Self {
presets: HashMap::new(),
};
manager.load_builtin_presets();
manager
}
#[allow(clippy::too_many_lines)]
fn load_builtin_presets(&mut self) {
self.presets.insert(
"transcode-web".to_string(),
JobPreset {
name: "transcode-web".to_string(),
description: "Transcode for web delivery".to_string(),
operation: BatchOperation::Transcode {
preset: "web".to_string(),
},
priority: Priority::Normal,
retry: RetryPolicy::default(),
parameters: HashMap::new(),
},
);
self.presets.insert(
"transcode-mobile".to_string(),
JobPreset {
name: "transcode-mobile".to_string(),
description: "Transcode for mobile devices".to_string(),
operation: BatchOperation::Transcode {
preset: "mobile".to_string(),
},
priority: Priority::Normal,
retry: RetryPolicy::default(),
parameters: HashMap::new(),
},
);
self.presets.insert(
"transcode-broadcast".to_string(),
JobPreset {
name: "transcode-broadcast".to_string(),
description: "Transcode for broadcast delivery".to_string(),
operation: BatchOperation::Transcode {
preset: "broadcast".to_string(),
},
priority: Priority::High,
retry: RetryPolicy::default(),
parameters: HashMap::new(),
},
);
self.presets.insert(
"qc-full".to_string(),
JobPreset {
name: "qc-full".to_string(),
description: "Full quality control check".to_string(),
operation: BatchOperation::QualityCheck {
profile: "full".to_string(),
},
priority: Priority::Normal,
retry: RetryPolicy::default(),
parameters: HashMap::new(),
},
);
self.presets.insert(
"qc-quick".to_string(),
JobPreset {
name: "qc-quick".to_string(),
description: "Quick quality control check".to_string(),
operation: BatchOperation::QualityCheck {
profile: "quick".to_string(),
},
priority: Priority::Normal,
retry: RetryPolicy::default(),
parameters: HashMap::new(),
},
);
self.presets.insert(
"analyze-video".to_string(),
JobPreset {
name: "analyze-video".to_string(),
description: "Analyze video quality".to_string(),
operation: BatchOperation::Analyze {
analysis_type: AnalysisType::VideoQuality,
},
priority: Priority::Low,
retry: RetryPolicy::default(),
parameters: HashMap::new(),
},
);
self.presets.insert(
"analyze-audio".to_string(),
JobPreset {
name: "analyze-audio".to_string(),
description: "Analyze audio levels".to_string(),
operation: BatchOperation::Analyze {
analysis_type: AnalysisType::AudioLevel,
},
priority: Priority::Low,
retry: RetryPolicy::default(),
parameters: HashMap::new(),
},
);
self.presets.insert(
"detect-scenes".to_string(),
JobPreset {
name: "detect-scenes".to_string(),
description: "Detect scene changes".to_string(),
operation: BatchOperation::Analyze {
analysis_type: AnalysisType::SceneDetection,
},
priority: Priority::Low,
retry: RetryPolicy::default(),
parameters: HashMap::new(),
},
);
self.presets.insert(
"detect-black".to_string(),
JobPreset {
name: "detect-black".to_string(),
description: "Detect black frames".to_string(),
operation: BatchOperation::Analyze {
analysis_type: AnalysisType::BlackFrameDetection,
},
priority: Priority::Low,
retry: RetryPolicy::default(),
parameters: HashMap::new(),
},
);
self.presets.insert(
"detect-silence".to_string(),
JobPreset {
name: "detect-silence".to_string(),
description: "Detect audio silence".to_string(),
operation: BatchOperation::Analyze {
analysis_type: AnalysisType::SilenceDetection,
},
priority: Priority::Low,
retry: RetryPolicy::default(),
parameters: HashMap::new(),
},
);
self.presets.insert(
"measure-loudness".to_string(),
JobPreset {
name: "measure-loudness".to_string(),
description: "Measure audio loudness".to_string(),
operation: BatchOperation::Analyze {
analysis_type: AnalysisType::LoudnessMeasurement,
},
priority: Priority::Normal,
retry: RetryPolicy::default(),
parameters: HashMap::new(),
},
);
self.presets.insert(
"copy-files".to_string(),
JobPreset {
name: "copy-files".to_string(),
description: "Copy files".to_string(),
operation: BatchOperation::FileOp {
operation: FileOperation::Copy { overwrite: false },
},
priority: Priority::Normal,
retry: RetryPolicy::default(),
parameters: HashMap::new(),
},
);
self.presets.insert(
"move-files".to_string(),
JobPreset {
name: "move-files".to_string(),
description: "Move files".to_string(),
operation: BatchOperation::FileOp {
operation: FileOperation::Move { overwrite: false },
},
priority: Priority::Normal,
retry: RetryPolicy::default(),
parameters: HashMap::new(),
},
);
self.presets.insert(
"create-archive".to_string(),
JobPreset {
name: "create-archive".to_string(),
description: "Create archive".to_string(),
operation: BatchOperation::FileOp {
operation: FileOperation::Archive {
format: crate::operations::file_ops::ArchiveFormat::Zip,
compression: 6,
},
},
priority: Priority::Normal,
retry: RetryPolicy::default(),
parameters: HashMap::new(),
},
);
self.presets.insert(
"checksum".to_string(),
JobPreset {
name: "checksum".to_string(),
description: "Calculate file checksums".to_string(),
operation: BatchOperation::FileOp {
operation: FileOperation::Checksum {
algorithm: crate::operations::file_ops::HashAlgorithm::Sha256,
},
},
priority: Priority::Low,
retry: RetryPolicy::default(),
parameters: HashMap::new(),
},
);
}
#[must_use]
pub fn get(&self, name: &str) -> Option<&JobPreset> {
self.presets.get(name)
}
#[must_use]
pub fn list(&self) -> Vec<String> {
self.presets.keys().cloned().collect()
}
pub fn add(&mut self, preset: JobPreset) {
self.presets.insert(preset.name.clone(), preset);
}
pub fn remove(&mut self, name: &str) -> Option<JobPreset> {
self.presets.remove(name)
}
}
impl Default for PresetManager {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_preset_manager_creation() {
let manager = PresetManager::new();
assert!(!manager.presets.is_empty());
}
#[test]
fn test_get_preset() {
let manager = PresetManager::new();
let preset = manager.get("transcode-web");
assert!(preset.is_some());
}
#[test]
fn test_list_presets() {
let manager = PresetManager::new();
let presets = manager.list();
assert!(presets.contains(&"transcode-web".to_string()));
}
#[test]
fn test_add_custom_preset() {
let mut manager = PresetManager::new();
let preset = JobPreset {
name: "custom".to_string(),
description: "Custom preset".to_string(),
operation: BatchOperation::FileOp {
operation: FileOperation::Copy { overwrite: false },
},
priority: Priority::Normal,
retry: RetryPolicy::default(),
parameters: HashMap::new(),
};
manager.add(preset);
assert!(manager.get("custom").is_some());
}
#[test]
fn test_remove_preset() {
let mut manager = PresetManager::new();
let preset = manager.remove("transcode-web");
assert!(preset.is_some());
assert!(manager.get("transcode-web").is_none());
}
#[test]
fn test_create_job_from_preset() {
let manager = PresetManager::new();
let preset = manager.get("transcode-web").expect("failed to get value");
let job = preset.create_job("test-job".to_string());
assert_eq!(job.name, "test-job");
assert_eq!(job.priority, Priority::Normal);
}
}