use crate::errors::{SageError, SageResult};
use winreg::enums::*;
use winreg::RegKey;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SageModule {
Comptabilite,
Commercial,
}
impl SageModule {
fn prog_id(&self) -> &'static str {
match self {
SageModule::Comptabilite => "Objets100c.Cpta.Stream",
SageModule::Commercial => "Objets100c.Cial.Stream",
}
}
fn display_name(&self) -> &'static str {
match self {
SageModule::Comptabilite => "Sage Comptabilité",
SageModule::Commercial => "Sage Commercial",
}
}
}
pub fn resolve_prog_id(prog_id: &str) -> SageResult<String> {
let hkcr = RegKey::predef(HKEY_CLASSES_ROOT);
let prog_id_key = hkcr.open_subkey(prog_id).map_err(|e| {
SageError::RegistryError(format!(
"ProgID '{}' introuvable dans le registre: {}",
prog_id, e
))
})?;
let clsid_key = prog_id_key.open_subkey("CLSID").map_err(|e| {
SageError::RegistryError(format!(
"Clé CLSID absente pour ProgID '{}': {}",
prog_id, e
))
})?;
let clsid: String = clsid_key.get_value("").map_err(|e| {
SageError::RegistryError(format!(
"Valeur CLSID invalide pour ProgID '{}': {}",
prog_id, e
))
})?;
Ok(clsid.trim_matches(|c| c == '{' || c == '}').to_string())
}
fn find_module_versions(module: SageModule) -> SageResult<Vec<(String, String)>> {
let prog_id = module.prog_id();
match resolve_prog_id(prog_id) {
Ok(clsid) => Ok(vec![(prog_id.to_string(), clsid)]),
Err(_) => Err(SageError::RegistryError(format!(
"Aucune version de {} trouvée dans le registre. Vérifiez que Sage 100c est installé.",
module.display_name()
))),
}
}
fn find_latest_module(module: SageModule) -> SageResult<(String, String)> {
let versions = find_module_versions(module)?;
versions.into_iter().next().ok_or_else(|| {
SageError::RegistryError(format!("Aucune version {} trouvée", module.display_name()))
})
}
pub fn find_bscpta_versions() -> SageResult<Vec<(String, String)>> {
find_module_versions(SageModule::Comptabilite)
}
pub fn find_latest_bscpta() -> SageResult<(String, String)> {
find_latest_module(SageModule::Comptabilite)
}
pub fn find_bscial_versions() -> SageResult<Vec<(String, String)>> {
find_module_versions(SageModule::Commercial)
}
pub fn find_latest_bscial() -> SageResult<(String, String)> {
find_latest_module(SageModule::Commercial)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_find_bscpta_versions() {
match find_bscpta_versions() {
Ok(versions) => {
println!("✅ Versions BSCpta trouvées:");
for (prog_id, clsid) in versions {
println!(" - {} -> {}", prog_id, clsid);
}
}
Err(e) => println!("⚠️ Aucune version BSCpta trouvée: {}", e),
}
}
#[test]
fn test_find_latest_bscpta() {
match find_latest_bscpta() {
Ok((prog_id, clsid)) => {
println!("✅ Dernière version BSCpta: {} ({})", prog_id, clsid);
}
Err(e) => println!("⚠️ Erreur: {}", e),
}
}
#[test]
fn test_find_bscial_versions() {
match find_bscial_versions() {
Ok(versions) => {
println!("✅ Versions BSCial trouvées:");
for (prog_id, clsid) in versions {
println!(" - {} -> {}", prog_id, clsid);
}
}
Err(e) => println!("⚠️ Aucune version BSCial trouvée: {}", e),
}
}
#[test]
fn test_find_latest_bscial() {
match find_latest_bscial() {
Ok((prog_id, clsid)) => {
println!("✅ Dernière version BSCial: {} ({})", prog_id, clsid);
}
Err(e) => println!("⚠️ Erreur: {}", e),
}
}
#[test]
fn test_resolve_prog_id_bscpta() {
match resolve_prog_id("Sage.BSCpta.Application.100c") {
Ok(clsid) => {
println!("✅ CLSID BSCpta résolu: {}", clsid);
assert_eq!(clsid, "309DE0FB-9FB8-4F4E-8295-CC60C60DAA33");
}
Err(e) => println!(
"⚠️ ProgID BSCpta non trouvé (normal si Sage non installé): {}",
e
),
}
}
#[test]
fn test_resolve_prog_id_bscial() {
match resolve_prog_id("Sage.BSCial.Application.100c") {
Ok(clsid) => {
println!("✅ CLSID BSCial résolu: {}", clsid);
}
Err(e) => println!(
"⚠️ ProgID BSCial non trouvé (normal si Sage non installé): {}",
e
),
}
}
}