use anyhow::{Result, Context};
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::Path;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct WindowConfig {
pub name: String,
pub start: String, pub end: String, }
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct JobConfig {
pub name: String,
pub url: String,
pub days: Vec<String>, pub windows: Vec<WindowConfig>,
pub extract_prompt: String,
pub output_path: String,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ScheduleConfig {
pub jobs: Vec<JobConfig>,
}
impl ScheduleConfig {
pub fn load_or_create() -> Result<Self> {
let config_dir = Path::new("config");
if !config_dir.exists() {
fs::create_dir_all(config_dir).context("No se pudo crear el directorio config")?;
}
let config_path = config_dir.join("schedule.json");
if config_path.exists() {
let content = fs::read_to_string(config_path)?;
let config: ScheduleConfig = serde_json::from_str(&content)
.context("Error al parsear config/schedule.json")?;
Ok(config)
} else {
let default_config = ScheduleConfig {
jobs: vec![JobConfig {
name: "tasas_bcv".to_string(),
url: "https://www.bcv.org.ve/".to_string(),
days: vec![
"Mon".to_string(),
"Tue".to_string(),
"Wed".to_string(),
"Thu".to_string(),
"Fri".to_string(),
],
windows: vec![
WindowConfig {
name: "AM".to_string(),
start: "09:00".to_string(),
end: "12:59".to_string(),
},
WindowConfig {
name: "PM".to_string(),
start: "13:00".to_string(),
end: "18:00".to_string(),
},
],
extract_prompt: "Extrae el valor numérico de venta oficial del Dólar (USD) y del Euro (EUR) según el Banco Central de Venezuela en un JSON estructurado con claves 'USD' y 'EUR'.".to_string(),
output_path: "downloads/bcv_rates.json".to_string(),
}],
};
let json_content = serde_json::to_string_pretty(&default_config)?;
fs::write(config_path, json_content)?;
Ok(default_config)
}
}
}