dixscript 1.0.0

Config, code, and encryption in one file — a data interchange format with compile-time functions, AES-256/ChaCha20 built-in, and cross-platform FFI
Documentation
use std::fs;
use crate::ErrorManager::ErrorManager;

pub struct DiagnosticDumper {
    error_manager: ErrorManager,
}

impl DiagnosticDumper {
    pub fn new() -> Self {
        DiagnosticDumper {
            error_manager: ErrorManager::get_shared_instance(),
        }
    }

    pub fn generate_dump(&self) -> String {
        let mut output = String::new();

        self.write_header(&mut output);
        self.write_separator(&mut output);

        self.write_log_contents(&mut output);
        self.write_separator(&mut output);

        self.write_error_summary(&mut output);
        self.write_separator(&mut output);

        self.write_all_errors(&mut output);
        self.write_separator(&mut output);

        self.write_footer(&mut output);

        output
    }

    pub fn dump_to_file(&self, filename: &str) -> Result<String, String> {
        let content = self.generate_dump();

        let current_dir = std::env::current_dir()
            .map_err(|e| format!("Failed to get current directory: {}", e))?;

        let mut project_dir = current_dir.clone();
        loop {
            if project_dir.join("../../Cargo.toml").exists() {
                break;
            }
            match project_dir.parent() {
                Some(parent) => project_dir = parent.to_path_buf(),
                None => {
                    project_dir = current_dir;
                    break;
                }
            }
        }

        let filepath = project_dir.join(filename);

        fs::write(&filepath, &content)
            .map_err(|e| format!("Failed to write diagnostic dump: {}", e))?;

        let filepath_str = filepath.to_string_lossy().to_string();
        println!("[DiagnosticDumper] Full diagnostic dump saved to: {}", filepath_str);

        Ok(filepath_str)
    }

    fn get_machine_name() -> String {
        #[cfg(not(target_arch = "wasm32"))]
        {
            hostname::get()
                .unwrap_or_default()
                .to_string_lossy()
                .to_string()
        }

        #[cfg(target_arch = "wasm32")]
        {
            "wasm32-unknown-unknown".to_string()
        }
    }

    fn write_header(&self, output: &mut String) {
        use std::fmt::Write;

        writeln!(output, "╔════════════════════════════════════════════════════════════════════════════╗").unwrap();
        writeln!(output, "║                    DIXSCRIPT DIAGNOSTIC DUMP                               ║").unwrap();
        writeln!(output, "╚════════════════════════════════════════════════════════════════════════════╝").unwrap();
        writeln!(output).unwrap();
        writeln!(output, "Generated: {}", chrono::Local::now().format("%Y-%m-%d %H:%M:%S.%3f")).unwrap();
        writeln!(output, "Machine: {}", Self::get_machine_name()).unwrap();
        writeln!(output, "User: {}", std::env::var("USER").or_else(|_| std::env::var("USERNAME")).unwrap_or_else(|_| "unknown".to_string())).unwrap();
        writeln!(output, "Working Directory: {}", std::env::current_dir().unwrap_or_default().display()).unwrap();
        writeln!(output).unwrap();

        let debug_info = self.error_manager.get_debug_info();
        writeln!(output, "ErrorManager State:").unwrap();
        writeln!(output, "  Version: {}", debug_info.get("version").unwrap_or(&"unknown".to_string())).unwrap();
        writeln!(output, "  Error Handling Strategy: {}", debug_info.get("error_handling_strategy").unwrap_or(&"unknown".to_string())).unwrap();
        writeln!(output, "  Debug Mode: {}", debug_info.get("debug_mode").unwrap_or(&"unknown".to_string())).unwrap();
        writeln!(output, "  Has Errors: {}", debug_info.get("has_errors").unwrap_or(&"false".to_string())).unwrap();
        writeln!(output, "  Total Errors: {}", debug_info.get("total_errors").unwrap_or(&"0".to_string())).unwrap();
        writeln!(output).unwrap();
    }

    fn write_footer(&self, output: &mut String) {
        use std::fmt::Write;

        writeln!(output).unwrap();
        writeln!(output, "╔════════════════════════════════════════════════════════════════════════════╗").unwrap();
        writeln!(output, "║                        END OF DIAGNOSTIC DUMP                              ║").unwrap();
        writeln!(output, "╚════════════════════════════════════════════════════════════════════════════╝").unwrap();
    }

    fn write_separator(&self, output: &mut String) {
        use std::fmt::Write;

        writeln!(output).unwrap();
        writeln!(output, "================================================================================").unwrap();
        writeln!(output).unwrap();
    }

    fn write_log_contents(&self, output: &mut String) {
        use std::fmt::Write;

        writeln!(output, "█████ COMPLETE LOG CONTENTS █████").unwrap();
        writeln!(output).unwrap();

        let log_contents = self.error_manager.get_log_contents();

        if log_contents.is_empty() {
            writeln!(output, "  [No log entries]").unwrap();
        } else {
            writeln!(output, "{}", log_contents).unwrap();
        }
    }

    fn write_error_summary(&self, output: &mut String) {
        use std::fmt::Write;

        writeln!(output, "█████ ERROR SUMMARY █████").unwrap();
        writeln!(output).unwrap();

        let counts = self.error_manager.get_error_counts_by_severity();

        writeln!(output, "By Severity:").unwrap();
        writeln!(output, "  Info:    {}", counts.get(&crate::ErrorManager::ErrorSeverity::Info).unwrap_or(&0)).unwrap();
        writeln!(output, "  Warning: {}", counts.get(&crate::ErrorManager::ErrorSeverity::Warning).unwrap_or(&0)).unwrap();
        writeln!(output, "  Error:   {}", counts.get(&crate::ErrorManager::ErrorSeverity::Error).unwrap_or(&0)).unwrap();
        writeln!(output, "  Fatal:   {}", counts.get(&crate::ErrorManager::ErrorSeverity::Fatal).unwrap_or(&0)).unwrap();
        writeln!(output).unwrap();

        writeln!(output, "By Category:").unwrap();
        writeln!(output, "  Config:               {}", self.error_manager.get_config_errors().len()).unwrap();
        writeln!(output, "  Lexical:              {}", self.error_manager.get_lexical_errors().len()).unwrap();
        writeln!(output, "  Parse:                {}", self.error_manager.get_parse_errors().len()).unwrap();
        writeln!(output, "  Registry:             {}", self.error_manager.get_registry_errors().len()).unwrap();
        writeln!(output, "  ImportsResolution:    {}", self.error_manager.get_imports_resolution_errors().len()).unwrap();
        writeln!(output, "  Semantic:             {}", self.error_manager.get_semantic_errors().len()).unwrap();
        writeln!(output, "  AstEnhancement:       {}", self.error_manager.get_ast_enhancement_errors().len()).unwrap();
        writeln!(output, "  ValueResolution:      {}", self.error_manager.get_value_resolution_errors().len()).unwrap();
        writeln!(output, "  DLM:                  {}", self.error_manager.get_dlm_errors().len()).unwrap();
        writeln!(output, "  BinarySerialization:  {}", self.error_manager.get_binary_serialization_errors().len()).unwrap();
        writeln!(output, "  Runtime:              {}", self.error_manager.get_runtime_errors().len()).unwrap();
        writeln!(output, "  General:              {}", self.error_manager.get_general_errors().len()).unwrap();
    }

    fn write_all_errors(&self, output: &mut String) {
        use std::fmt::Write;

        writeln!(output, "█████ DETAILED ERROR BREAKDOWN █████").unwrap();
        writeln!(output).unwrap();

        self.write_config_errors(output);
        self.write_lexical_errors(output);
        self.write_parse_errors(output);
        self.write_imports_resolution_errors(output);
        self.write_semantic_errors(output);
        self.write_ast_enhancement_errors(output);
        self.write_value_resolution_errors(output);
        self.write_dlm_errors(output);
        self.write_binary_serialization_errors(output);
        self.write_runtime_errors(output);
        self.write_general_errors(output);
    }

    fn write_config_errors(&self, output: &mut String) {
        use std::fmt::Write;
        let errors = self.error_manager.get_config_errors();
        writeln!(output, "─── CONFIG ERRORS ({}) ───", errors.len()).unwrap();
        writeln!(output).unwrap();
        if errors.is_empty() {
            writeln!(output, "  [No config errors]").unwrap();
            writeln!(output).unwrap();
            return;
        }
        for error in errors { writeln!(output, "{}", error).unwrap(); }
    }

    fn write_lexical_errors(&self, output: &mut String) {
        use std::fmt::Write;
        let errors = self.error_manager.get_lexical_errors();
        writeln!(output, "─── LEXICAL ERRORS ({}) ───", errors.len()).unwrap();
        writeln!(output).unwrap();
        if errors.is_empty() {
            writeln!(output, "  [No lexical errors]").unwrap();
            writeln!(output).unwrap();
            return;
        }
        for error in errors { writeln!(output, "{}", error).unwrap(); }
    }

    fn write_parse_errors(&self, output: &mut String) {
        use std::fmt::Write;
        let errors = self.error_manager.get_parse_errors();
        writeln!(output, "─── PARSE ERRORS ({}) ───", errors.len()).unwrap();
        writeln!(output).unwrap();
        if errors.is_empty() {
            writeln!(output, "  [No parse errors]").unwrap();
            writeln!(output).unwrap();
            return;
        }
        for error in errors { writeln!(output, "{}", error).unwrap(); }
    }

    fn write_imports_resolution_errors(&self, output: &mut String) {
        use std::fmt::Write;
        let errors = self.error_manager.get_imports_resolution_errors();
        writeln!(output, "─── IMPORTS RESOLUTION ERRORS ({}) ───", errors.len()).unwrap();
        writeln!(output).unwrap();
        if errors.is_empty() {
            writeln!(output, "  [No imports resolution errors]").unwrap();
            writeln!(output).unwrap();
            return;
        }
        for error in errors { writeln!(output, "{}", error).unwrap(); }
    }

    fn write_semantic_errors(&self, output: &mut String) {
        use std::fmt::Write;
        let errors = self.error_manager.get_semantic_errors();
        writeln!(output, "─── SEMANTIC ERRORS ({}) ───", errors.len()).unwrap();
        writeln!(output).unwrap();
        if errors.is_empty() {
            writeln!(output, "  [No semantic errors]").unwrap();
            writeln!(output).unwrap();
            return;
        }
        for error in errors { writeln!(output, "{}", error).unwrap(); }
    }

    fn write_ast_enhancement_errors(&self, output: &mut String) {
        use std::fmt::Write;
        let errors = self.error_manager.get_ast_enhancement_errors();
        writeln!(output, "─── AST ENHANCEMENT ERRORS ({}) ───", errors.len()).unwrap();
        writeln!(output).unwrap();
        if errors.is_empty() {
            writeln!(output, "  [No AST enhancement errors]").unwrap();
            writeln!(output).unwrap();
            return;
        }
        for error in errors { writeln!(output, "{}", error).unwrap(); }
    }

    fn write_value_resolution_errors(&self, output: &mut String) {
        use std::fmt::Write;
        let errors = self.error_manager.get_value_resolution_errors();
        writeln!(output, "─── VALUE RESOLUTION ERRORS ({}) ───", errors.len()).unwrap();
        writeln!(output).unwrap();
        if errors.is_empty() {
            writeln!(output, "  [No value resolution errors]").unwrap();
            writeln!(output).unwrap();
            return;
        }
        for error in errors { writeln!(output, "{}", error).unwrap(); }
    }

    fn write_dlm_errors(&self, output: &mut String) {
        use std::fmt::Write;
        let errors = self.error_manager.get_dlm_errors();
        writeln!(output, "─── DLM ERRORS ({}) ───", errors.len()).unwrap();
        writeln!(output).unwrap();
        if errors.is_empty() {
            writeln!(output, "  [No DLM errors]").unwrap();
            writeln!(output).unwrap();
            return;
        }
        for error in errors { writeln!(output, "{}", error).unwrap(); }
    }

    fn write_binary_serialization_errors(&self, output: &mut String) {
        use std::fmt::Write;
        let errors = self.error_manager.get_binary_serialization_errors();
        writeln!(output, "─── BINARY SERIALIZATION ERRORS ({}) ───", errors.len()).unwrap();
        writeln!(output).unwrap();
        if errors.is_empty() {
            writeln!(output, "  [No binary serialization errors]").unwrap();
            writeln!(output).unwrap();
            return;
        }
        for error in errors { writeln!(output, "{}", error).unwrap(); }
    }

    fn write_runtime_errors(&self, output: &mut String) {
        use std::fmt::Write;
        let errors = self.error_manager.get_runtime_errors();
        writeln!(output, "─── RUNTIME ERRORS ({}) ───", errors.len()).unwrap();
        writeln!(output).unwrap();
        if errors.is_empty() {
            writeln!(output, "  [No runtime errors]").unwrap();
            writeln!(output).unwrap();
            return;
        }
        for error in errors { writeln!(output, "{}", error).unwrap(); }
    }

    fn write_general_errors(&self, output: &mut String) {
        use std::fmt::Write;
        let errors = self.error_manager.get_general_errors();
        writeln!(output, "─── GENERAL ERRORS ({}) ───", errors.len()).unwrap();
        writeln!(output).unwrap();
        if errors.is_empty() {
            writeln!(output, "  [No general errors]").unwrap();
            writeln!(output).unwrap();
            return;
        }
        for error in errors { writeln!(output, "{}", error).unwrap(); }
    }
}

impl Default for DiagnosticDumper {
    fn default() -> Self { Self::new() }
            }