use std::sync::Arc;
use std::collections::HashMap;
use chrono::Utc;
use crate::ecosystem::types::*;
use super::*;
use std::collections::{BTreeMap};
#[derive(Debug, Clone)]
pub struct VersionManager {
registry: Arc<ModuleRegistry>,
versions: HashMap<String, Vec<ModuleVersion>>,
}
impl VersionManager {
pub fn new(registry: Arc<ModuleRegistry>) -> Self {
let mut manager = Self {
registry,
versions: HashMap::new(),
};
manager.initialize_test_versions();
manager
}
fn initialize_test_versions(&mut self) {
self.versions.insert(
"dep-x".to_string(),
vec![
ModuleVersion {
version: Version::parse("1.0.0").unwrap(),
published_at: Utc::now(),
downloads: 1000,
},
ModuleVersion {
version: Version::parse("1.5.0").unwrap(),
published_at: Utc::now(),
downloads: 5000,
},
ModuleVersion {
version: Version::parse("2.0.0").unwrap(),
published_at: Utc::now(),
downloads: 10000,
},
],
);
self.versions.insert(
"dep-y".to_string(),
vec![
ModuleVersion {
version: Version::parse("2.0.0").unwrap(),
published_at: Utc::now(),
downloads: 3000,
},
ModuleVersion {
version: Version::parse("2.5.0").unwrap(),
published_at: Utc::now(),
downloads: 8000,
},
],
);
}
pub async fn publish_version(&self, version: &ModuleVersion) -> Result<(), Box<dyn std::error::Error>> {
let module_name: _ = &format!("module-{}", version.version));
println!("Publishing version {}@{}", module_name, version.version);
Ok(())
}
pub async fn rollback_version(&self, module_id: &ModuleId, target_version: &Version) -> Result<(), Box<dyn std::error::Error>> {
println!("Rolling back {} to version {}", module_id.name, target_version);
Ok(())
}
pub async fn distribute_to_cdn(&self, module: &ModuleInfo) -> Result<CDNEndpoints, Box<dyn std::error::Error>> {
let endpoints: _ = CDNEndpoints {
primary: format!("https://cdn.amberjs.dev/modules/{}/latest", module.name),
mirrors: vec![
format!("https://cdn-us.amberjs.dev/modules/{}/latest", module.name),
format!("https://cdn-eu.amberjs.dev/modules/{}/latest", module.name),
format!("https://cdn-asia.amberjs.dev/modules/{}/latest", module.name),
],
};
println!("Distributed {}@{} to CDN", module.name, module.module_id.version);
Ok(endpoints)
}
pub fn get_versions(&self, module_name: &str) -> Option<&Vec<ModuleVersion> {
self.versions.get(module_name)
}
pub fn get_latest_version(&self, module_name: &str) -> Option<&ModuleVersion> {
self.versions.get(module_name)
.and_then(|versions| versions.iter().max_by(|a, b| {
a.version.to_string().cmp(&b.version.to_string())
}))
}
pub fn get_stable_version(&self, module_name: &str) -> Option<&ModuleVersion> {
self.get_latest_version(module_name)
}
pub fn can_upgrade(&self, current: &Version, target: &Version) -> bool {
target.to_string() > current.to_string()
}
pub fn version_distance(&self, v1: &Version, v2: &Version) -> u32 {
let major_diff: _ = if v1.major > v2.major {
v1.major - v2.major
} else {
v2.major - v1.major
};
let minor_diff: _ = if v1.minor > v2.minor {
v1.minor - v2.minor
} else {
v2.minor - v1.minor
};
let patch_diff: _ = if v1.patch > v2.patch {
v1.patch - v2.patch
} else {
v2.patch - v1.patch
};
(major_diff * 100 + minor_diff * 10 + patch_diff) as u32
}
}