use std::collections::HashSet;
use crate::Compiler::Core::Tokenizer::TokenType;
use std::sync::{LazyLock, RwLock};
pub const VERSION_1_0: &str = "1.0.0";
pub const DEFAULT_VERSION: &str = VERSION_1_0;
pub struct VersionManager {
current_version: String,
version_hierarchy: HashSet<String>,
feature_map: HashSet<String>,
}
static VERSION_MANAGER: LazyLock<RwLock<VersionManager>> = LazyLock::new(|| {
RwLock::new(VersionManager::new(DEFAULT_VERSION))
});
impl VersionManager {
fn new(version: &str) -> Self {
let validated_version = Self::validate_version_static(version);
let feature_map = Self::initialize_features_for_version(&validated_version);
let mut version_hierarchy = HashSet::new();
version_hierarchy.insert(VERSION_1_0.to_string());
VersionManager {
current_version: validated_version,
version_hierarchy,
feature_map,
}
}
pub fn instance() -> &'static RwLock<VersionManager> {
&VERSION_MANAGER
}
pub fn initialize(version: &str) {
let validated = Self::validate_version_static(version);
if let Ok(manager) = VERSION_MANAGER.read() {
if manager.current_version == validated {
return;
}
}
if let Ok(mut manager) = VERSION_MANAGER.write() {
if manager.current_version != validated {
manager.current_version = validated.clone();
manager.feature_map = Self::initialize_features_for_version(&validated);
}
}
}
fn validate_version_static(version: &str) -> String {
if version.is_empty() || version != VERSION_1_0 {
DEFAULT_VERSION.to_string()
} else {
version.to_string()
}
}
pub fn current_version(&self) -> &str {
&self.current_version
}
pub fn get_current_version(&self) -> &str {
&self.current_version
}
#[inline]
pub fn supports_feature(&self, feature_key: &str) -> bool {
self.feature_map.contains(&feature_key.to_string())
}
pub fn is_compatible_with(&self, target_version: &str) -> bool {
self.version_hierarchy.contains(&target_version.to_string())
}
pub fn is_token_valid_for_version(&self, token_type: &TokenType) -> bool {
match token_type {
TokenType::SectionConfig => self.supports_feature("config_section"),
TokenType::SectionImports => self.supports_feature("imports_section"),
TokenType::SectionQuickFuncs => self.supports_feature("quickfuncs_section"),
TokenType::SectionEnums => self.supports_feature("enums_section"),
TokenType::SectionDLM => self.supports_feature("dlm_section"),
TokenType::SectionData => self.supports_feature("data_section"),
TokenType::SectionSecurity => self.supports_feature("security_section"),
_ => true,
}
}
pub fn supports_section_type(&self, section_type: &str) -> bool {
let section_feature = format!("{}_section", section_type.to_lowercase());
self.supports_feature(§ion_feature)
}
#[inline]
pub fn supports_feature_control(&self) -> bool {
self.supports_feature("feature_control")
}
#[inline]
pub fn supports_builtin_registry(&self) -> bool {
self.supports_feature("static_object_registry")
&& self.supports_feature("instance_method_registry")
}
#[inline]
pub fn supports_dual_parsers(&self) -> bool {
self.supports_feature("dual_parser_system")
}
pub fn get_recommended_parser(&self, section_type: &str) -> &'static str {
match section_type.to_uppercase().as_str() {
"CONFIG" | "DLM" | "DATA" | "ENUMS" | "SECURITY" | "IMPORTS" => "LL",
"QUICKFUNCS" => "LALR",
_ => "LL",
}
}
pub fn validate_script_features(&self, script: &crate::Compiler::AST::DixScript) -> Vec<String> {
let mut unsupported = Vec::new();
if script.config.is_some() && !self.supports_feature("config_section") {
unsupported.push("CONFIG section".to_string());
}
if script.imports.is_some() && !self.supports_feature("imports_section") {
unsupported.push("IMPORTS section".to_string());
}
if script.dlm.is_some() && !self.supports_feature("dlm_section") {
unsupported.push("DLM section".to_string());
}
if script.enums.is_some() && !self.supports_feature("enums_section") {
unsupported.push("ENUMS section".to_string());
}
if script.quick_functions.is_some() && !self.supports_feature("quickfuncs_section") {
unsupported.push("QUICKFUNCS section".to_string());
}
if script.data.is_some() && !self.supports_feature("data_section") {
unsupported.push("DATA section".to_string());
}
if script.security.is_some() && !self.supports_feature("security_section") {
unsupported.push("SECURITY section".to_string());
}
unsupported
}
pub fn get_version_info(&self) -> std::collections::HashMap<String, String> {
let mut info = std::collections::HashMap::new();
info.insert("CurrentVersion".to_string(), self.current_version.clone());
info.insert("SupportedVersions".to_string(), VERSION_1_0.to_string());
info.insert("FeatureCount".to_string(), self.feature_map.len().to_string());
info.insert("CompatibilityMode".to_string(), "v1.0.0 Foundation".to_string());
info.insert("BackwardCompatibility".to_string(), "None (foundation version)".to_string());
info.insert("ForwardCompatibility".to_string(), "Limited (unknown features handled gracefully)".to_string());
info.insert("SupportsImports".to_string(), self.supports_feature("imports_section").to_string());
info
}
fn initialize_features_for_version(version: &str) -> HashSet<String> {
if version != VERSION_1_0 {
return HashSet::new();
}
let mut features = HashSet::new();
features.insert("basic_types".to_string());
features.insert("enhanced_types".to_string());
features.insert("data_types_with_annotations".to_string());
features.insert("config_section".to_string());
features.insert("imports_section".to_string());
features.insert("dlm_section".to_string());
features.insert("enums_section".to_string());
features.insert("quickfuncs_section".to_string());
features.insert("data_section".to_string());
features.insert("security_section".to_string());
features.insert("feature_control".to_string());
features.insert("debug_modes".to_string());
features.insert("config_constants".to_string());
features.insert("imports_local".to_string());
features.insert("imports_cloud".to_string());
features.insert("imports_verification".to_string());
features.insert("imports_namespaces".to_string());
features.insert("imports_nested".to_string());
features.insert("imports_cycle_detection".to_string());
features.insert("dlm_dcompressor".to_string());
features.insert("dlm_dauditor".to_string());
features.insert("dlm_dencryptor".to_string());
features.insert("table_group_syntax".to_string());
features.insert("group_arrays".to_string());
features.insert("simple_properties".to_string());
features.insert("object_properties".to_string());
features.insert("property_type_annotations".to_string());
features.insert("quickfunctions".to_string());
features.insert("function_scoping".to_string());
features.insert("function_type_annotations".to_string());
features.insert("function_parameters".to_string());
features.insert("quickfunc_calls_in_data".to_string());
features.insert("parameter_defaults".to_string());
features.insert("imported_function_calls".to_string());
features.insert("expressions_full".to_string());
features.insert("conditional_expressions".to_string());
features.insert("property_access".to_string());
features.insert("index_access".to_string());
features.insert("method_chaining".to_string());
features.insert("static_object_registry".to_string());
features.insert("instance_method_registry".to_string());
features.insert("dix_function_calls".to_string());
features.insert("if_elif_else".to_string());
features.insert("switch_statements".to_string());
features.insert("return_statements".to_string());
features.insert("interpolated_strings".to_string());
features.insert("single_quoted_strings".to_string());
features.insert("double_quoted_strings".to_string());
features.insert("array_literals".to_string());
features.insert("object_literals".to_string());
features.insert("prefixed_constructors".to_string());
features.insert("hex_colors".to_string());
features.insert("hex_literals".to_string());
features.insert("scientific_notation".to_string());
features.insert("date_literals".to_string());
features.insert("timestamp_literals".to_string());
features.insert("config_access".to_string());
features.insert("enum_access".to_string());
features.insert("imported_enum_access".to_string());
features.insert("qualified_identifiers".to_string());
features.insert("dual_parser_system".to_string());
features.insert("section_routing".to_string());
features.insert("context_aware_tokenization".to_string());
features.insert("forward_compatibility".to_string());
features.insert("version_constraints".to_string());
features.insert("compatibility_modes".to_string());
features.insert("mdix_extension".to_string());
features.insert("single_file_format".to_string());
features.insert("semantic_analysis".to_string());
features.insert("type_checking".to_string());
features.insert("scope_validation".to_string());
features.insert("built_in_validation".to_string());
features
}
}
pub fn extract_version_from_ast(script: &crate::Compiler::AST::DixScript) -> String {
if let Some(ref config) = script.config {
for entry in &config.entries {
if entry.key.eq_ignore_ascii_case("version") {
if let crate::Compiler::AST::ConfigValue::String(ref version) = entry.value {
return version.clone();
}
}
}
}
DEFAULT_VERSION.to_string()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_version_manager_singleton() {
let manager = VERSION_MANAGER.read().unwrap();
assert_eq!(manager.get_current_version(), VERSION_1_0);
}
#[test]
fn test_feature_support() {
let manager = VERSION_MANAGER.read().unwrap();
assert!(manager.supports_feature("config_section"));
assert!(manager.supports_feature("imports_section"));
assert!(manager.supports_feature("quickfuncs_section"));
assert!(!manager.supports_feature("nonexistent_feature"));
}
#[test]
fn test_version_compatibility() {
let manager = VERSION_MANAGER.read().unwrap();
assert!(manager.is_compatible_with(VERSION_1_0));
}
#[test]
fn test_section_support() {
let manager = VERSION_MANAGER.read().unwrap();
assert!(manager.supports_section_type("CONFIG"));
assert!(manager.supports_section_type("IMPORTS"));
assert!(manager.supports_section_type("QUICKFUNCS"));
}
#[test]
fn test_initialize_idempotent() {
VersionManager::initialize("1.0.0");
VersionManager::initialize("1.0.0");
VersionManager::initialize("1.0.0");
let manager = VERSION_MANAGER.read().unwrap();
assert_eq!(manager.get_current_version(), VERSION_1_0);
}
}