use crate::config::ModelConfig;
use crate::io::sanitizer::sanitize_api_key;
use crate::presets::preset::Preset;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fs;
use std::path::Path;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExportPackage {
pub version: String,
pub exported_at: DateTime<Utc>,
pub presets: Vec<Preset>,
#[serde(skip_serializing_if = "Option::is_none")]
pub model_configs: Option<HashMap<String, SanitizedModelConfig>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub active_config: Option<HashMap<String, String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SanitizedModelConfig {
pub api_key: String,
pub base_url: String,
pub model: String,
}
pub fn export_presets(presets: &[Preset], output_path: &Path) -> anyhow::Result<()> {
let package = ExportPackage {
version: "1.0.0".to_string(),
exported_at: Utc::now(),
presets: presets.to_vec(),
model_configs: None,
active_config: None,
};
let json = serde_json::to_string_pretty(&package)?;
fs::write(output_path, json)?;
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let mut perms = fs::metadata(output_path)?.permissions();
perms.set_mode(0o600);
fs::set_permissions(output_path, perms)?;
}
Ok(())
}
pub fn export_with_model_configs(
presets: &[Preset],
model_configs: &HashMap<String, ModelConfig>,
output_path: &Path,
) -> anyhow::Result<()> {
let sanitized_configs: HashMap<String, SanitizedModelConfig> = model_configs
.iter()
.map(|(name, config)| {
let sanitized = SanitizedModelConfig {
api_key: sanitize_api_key(&config.api_key),
base_url: config.base_url.clone(),
model: config.model_id.clone(),
};
(name.clone(), sanitized)
})
.collect();
let package = ExportPackage {
version: "1.0.0".to_string(),
exported_at: Utc::now(),
presets: presets.to_vec(),
model_configs: Some(sanitized_configs),
active_config: None,
};
let json = serde_json::to_string_pretty(&package)?;
fs::write(output_path, json)?;
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let mut perms = fs::metadata(output_path)?.permissions();
perms.set_mode(0o600);
fs::set_permissions(output_path, perms)?;
}
Ok(())
}
pub fn export_single_preset(preset: &Preset, output_path: &Path) -> anyhow::Result<()> {
export_presets(&[preset.clone()], output_path)
}