use super::templates::*;
use crate::error::{OptimError, Result};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TemplateRegistry {
templates: HashMap<TemplateCategory, Vec<PluginTemplate>>,
template_lookup: HashMap<String, (TemplateCategory, usize)>,
metadata: RegistryMetadata,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RegistryMetadata {
pub version: String,
pub last_updated: chrono::DateTime<chrono::Utc>,
pub template_count: usize,
pub description: String,
}
impl TemplateRegistry {
pub fn new() -> Self {
Self {
templates: HashMap::new(),
template_lookup: HashMap::new(),
metadata: RegistryMetadata {
version: "1.0.0".to_string(),
last_updated: chrono::Utc::now(),
template_count: 0,
description: "OptiRS Plugin Template Registry".to_string(),
},
}
}
pub fn register_template(&mut self, template: PluginTemplate) -> Result<()> {
let category = template.structure.category;
let template_id = template.metadata.id.clone();
if self.template_lookup.contains_key(&template_id) {
return Err(OptimError::InvalidConfig(
format!("Template with ID '{}' already exists", template_id)
));
}
let templates = self.templates.entry(category).or_insert_with(Vec::new);
let index = templates.len();
templates.push(template);
self.template_lookup.insert(template_id, (category, index));
self.metadata.template_count += 1;
self.metadata.last_updated = chrono::Utc::now();
Ok(())
}
pub fn get_template(&self, template_id: &str) -> Option<&PluginTemplate> {
self.template_lookup.get(template_id)
.and_then(|(category, index)| {
self.templates.get(category)
.and_then(|templates| templates.get(*index))
})
}
pub fn get_templates_by_category(&self, category: TemplateCategory) -> Option<&Vec<PluginTemplate>> {
self.templates.get(&category)
}
pub fn get_templates_by_complexity(&self, complexity: ComplexityLevel) -> Vec<&PluginTemplate> {
self.templates
.values()
.flatten()
.filter(|t| t.structure.complexity == complexity)
.collect()
}
pub fn search_by_tag(&self, tag: &str) -> Vec<&PluginTemplate> {
self.templates
.values()
.flatten()
.filter(|t| t.metadata.tags.contains(&tag.to_string()))
.collect()
}
pub fn list_template_ids(&self) -> Vec<&String> {
self.template_lookup.keys().collect()
}
pub fn get_statistics(&self) -> RegistryStatistics {
let mut category_counts = HashMap::new();
let mut complexity_counts = HashMap::new();
for templates in self.templates.values() {
for template in templates {
*category_counts.entry(template.structure.category).or_insert(0) += 1;
*complexity_counts.entry(template.structure.complexity).or_insert(0) += 1;
}
}
RegistryStatistics {
total_templates: self.metadata.template_count,
category_counts,
complexity_counts,
last_updated: self.metadata.last_updated,
}
}
pub fn remove_template(&mut self, template_id: &str) -> Result<PluginTemplate> {
if let Some((category, index)) = self.template_lookup.remove(template_id) {
if let Some(templates) = self.templates.get_mut(&category) {
if index < templates.len() {
let removed_template = templates.remove(index);
for (_, (cat, idx)) in self.template_lookup.iter_mut() {
if *cat == category && *idx > index {
*idx -= 1;
}
}
self.metadata.template_count -= 1;
self.metadata.last_updated = chrono::Utc::now();
return Ok(removed_template);
}
}
}
Err(OptimError::InvalidConfig(
format!("Template '{}' not found", template_id)
))
}
pub fn clear(&mut self) {
self.templates.clear();
self.template_lookup.clear();
self.metadata.template_count = 0;
self.metadata.last_updated = chrono::Utc::now();
}
}
#[derive(Debug, Clone)]
pub struct RegistryStatistics {
pub total_templates: usize,
pub category_counts: HashMap<TemplateCategory, usize>,
pub complexity_counts: HashMap<ComplexityLevel, usize>,
pub last_updated: chrono::DateTime<chrono::Utc>,
}
impl Default for TemplateRegistry {
fn default() -> Self {
Self::new()
}
}