//! Consolidated Rhai bindings for all profiling functions

use super::error::ToRhaiError;
use rhai::Engine;

/// Register profiling module functions with the Rhai engine
pub fn register_profiling_module(engine: &mut Engine) -> Result<(), Box<rhai::EvalAltResult>> {
    // Register individual modules
    super::cpu::rhai::register_cpu_module(engine)?;
    super::memory::rhai::register_memory_module(engine)?;
    super::disk::rhai::register_disk_module(engine)?;
    super::network::rhai::register_network_module(engine)?;
    super::monitor::rhai::register_monitor_module(engine)?;
    super::report::rhai::register_report_module(engine)?;

    // Register system module functions
    register_system_module(engine)?;

    Ok(())
}

/// Register system module functions
fn register_system_module(engine: &mut Engine) -> Result<(), Box<rhai::EvalAltResult>> {
    // Register SystemProfile type
    engine.register_type::<super::system::SystemProfile>();

    // Register SystemProfile getters only (read-only for scripts)
    engine.register_get("hostname", |profile: &mut super::system::SystemProfile| {
        profile.hostname.clone()
    });
    engine.register_get("os_name", |profile: &mut super::system::SystemProfile| {
        profile.os_name.clone()
    });
    engine.register_get(
        "os_version",
        |profile: &mut super::system::SystemProfile| profile.os_version.clone(),
    );
    engine.register_get(
        "kernel_version",
        |profile: &mut super::system::SystemProfile| profile.kernel_version.clone(),
    );
    engine.register_get("cpu_model", |profile: &mut super::system::SystemProfile| {
        profile.cpu_model.clone()
    });
    engine.register_get("cpu_cores", |profile: &mut super::system::SystemProfile| {
        profile.cpu_cores as i64
    });
    engine.register_get(
        "cpu_threads",
        |profile: &mut super::system::SystemProfile| profile.cpu_threads as i64,
    );
    engine.register_get(
        "memory_total_bytes",
        |profile: &mut super::system::SystemProfile| profile.memory_total_bytes as i64,
    );
    engine.register_get(
        "numa_nodes",
        |profile: &mut super::system::SystemProfile| profile.numa_nodes.map(|n| n as i64),
    );

    engine.register_fn("SystemProfile", || {
        super::system::SystemProfile::detect()
            .to_rhai_error()
            .unwrap_or_else(|_| {
                super::logging::log_error("Failed to detect system profile");
                // Return a default profile for script compatibility
                super::system::SystemProfile {
                    hostname: "unknown".to_string(),
                    os_name: "unknown".to_string(),
                    os_version: "unknown".to_string(),
                    kernel_version: "unknown".to_string(),
                    cpu_model: "unknown".to_string(),
                    cpu_cores: 1,
                    cpu_threads: 1,
                    memory_total_bytes: 0,
                    numa_nodes: None,
                }
            })
    });

    // Configure engine for security (but allow print for hero-do compatibility)
    configure_engine_security(engine);

    super::network::rhai::register_network_module(engine)?;
    super::disk::rhai::register_disk_module(engine)?;
    super::memory::rhai::register_memory_module(engine)?;
    super::cpu::rhai::register_cpu_module(engine)?;
    super::report::rhai::register_report_module(engine)?;
    super::monitor::rhai::register_monitor_module(engine)?;

    Ok(())
}

/// Register profiling module functions with Rhai engine (strict security mode)
pub fn register_profiling_module_strict(
    engine: &mut Engine,
) -> Result<(), Box<rhai::EvalAltResult>> {
    // Register SystemProfile type
    engine.register_type::<super::system::SystemProfile>();

    // Register SystemProfile getters only (read-only for scripts)
    engine.register_get("hostname", |profile: &mut super::system::SystemProfile| {
        profile.hostname.clone()
    });
    engine.register_get("os_name", |profile: &mut super::system::SystemProfile| {
        profile.os_name.clone()
    });
    engine.register_get(
        "os_version",
        |profile: &mut super::system::SystemProfile| profile.os_version.clone(),
    );
    engine.register_get(
        "kernel_version",
        |profile: &mut super::system::SystemProfile| profile.kernel_version.clone(),
    );
    engine.register_get("cpu_model", |profile: &mut super::system::SystemProfile| {
        profile.cpu_model.clone()
    });
    engine.register_get("cpu_cores", |profile: &mut super::system::SystemProfile| {
        profile.cpu_cores as i64
    });
    engine.register_get(
        "cpu_threads",
        |profile: &mut super::system::SystemProfile| profile.cpu_threads as i64,
    );
    engine.register_get(
        "memory_total_bytes",
        |profile: &mut super::system::SystemProfile| profile.memory_total_bytes as i64,
    );
    engine.register_get(
        "numa_nodes",
        |profile: &mut super::system::SystemProfile| profile.numa_nodes.map(|n| n as i64),
    );

    engine.register_fn("SystemProfile", || {
        match super::system::SystemProfile::detect() {
            Ok(profile) => profile,
            Err(e) => {
                super::logging::log_error(&format!("Failed to detect system profile: {}", e));
                // Return a default profile for script compatibility
                super::system::SystemProfile {
                    hostname: "unknown".to_string(),
                    os_name: "unknown".to_string(),
                    os_version: "unknown".to_string(),
                    kernel_version: "unknown".to_string(),
                    cpu_model: "unknown".to_string(),
                    cpu_cores: 1,
                    cpu_threads: 1,
                    memory_total_bytes: 0,
                    numa_nodes: None,
                }
            }
        }
    });

    // Configure engine for strict security (disable print)
    configure_engine_security_strict(engine);

    super::network::rhai::register_network_module(engine)?;
    super::disk::rhai::register_disk_module(engine)?;
    super::memory::rhai::register_memory_module(engine)?;
    super::cpu::rhai::register_cpu_module(engine)?;
    super::report::rhai::register_report_module(engine)?;
    super::monitor::rhai::register_monitor_module(engine)?;

    Ok(())
}

/// Configure security settings for Rhai engine (hero-do compatible)
fn configure_engine_security(engine: &mut Engine) {
    // Disable potentially dangerous modules
    engine.disable_symbol("File");
    engine.disable_symbol("Dir");
    engine.disable_symbol("Env");
    engine.disable_symbol("Process");
    engine.disable_symbol("Command");
    engine.disable_symbol("Http");
    engine.disable_symbol("Tcp");
    engine.disable_symbol("Udp");

    // Limit execution time
    engine.set_max_operations(10000);

    // Disable debug functions but allow print for hero-do compatibility
    engine.disable_symbol("debug");
    engine.disable_symbol("inspect");
}

/// Configure strict security settings for Rhai engine (disable print)
fn configure_engine_security_strict(engine: &mut Engine) {
    // Disable potentially dangerous modules
    engine.disable_symbol("File");
    engine.disable_symbol("Dir");
    engine.disable_symbol("Env");
    engine.disable_symbol("Process");
    engine.disable_symbol("Command");
    engine.disable_symbol("Http");
    engine.disable_symbol("Tcp");
    engine.disable_symbol("Udp");

    // Limit execution time
    engine.set_max_operations(10000);

    // Disable all debug functions including print
    engine.disable_symbol("debug");
    engine.disable_symbol("print");
    engine.disable_symbol("inspect");
}
