mecha10-cli 0.1.47

Mecha10 CLI tool
Documentation
//! Simulation validation
//!
//! Functions for validating simulation configurations and catalogs.

use crate::paths;
use crate::sim::{EnvironmentCatalog, RobotProfile};
use anyhow::Result;
use std::path::{Path, PathBuf};

/// Validate mecha10.json for simulation generation
pub fn validate_config(config_path: &Path) -> Result<()> {
    println!("🔍 Validating configuration...\n");

    let profile = RobotProfile::from_config_file(config_path)?;

    println!("✅ Configuration is valid!\n");
    println!("Robot Profile:");
    println!("  Platform: {}", profile.platform);
    println!("  Sensors: {} configured", profile.sensors.len());
    println!("  Task Nodes: {} configured", profile.task_nodes.len());
    println!("  Capabilities: {}", profile.capabilities.join(", "));

    Ok(())
}

/// Validate environment catalog integrity
pub fn validate_catalog(verbose: bool, missing_only: bool) -> Result<()> {
    println!("🔍 Validating environment catalog...\n");

    let catalog_path = PathBuf::from(paths::framework::ROBOT_TASKS_CATALOG);
    let catalog = EnvironmentCatalog::load(&catalog_path)?;
    let base_path = PathBuf::from(paths::framework::ROBOT_TASKS_DIR);

    let mut total = 0;
    let mut implemented = 0;
    let mut missing = 0;
    let mut missing_envs = Vec::new();

    for env in &catalog.environments {
        total += 1;

        // Check if the .tscn file exists
        let full_path = base_path.join(&env.path);
        let exists = full_path.exists();

        if exists {
            implemented += 1;
            if !missing_only {
                if verbose {
                    println!("{} ({}):", env.name, env.id);
                    println!("   Path: {}", env.path);
                    println!("   Difficulty: {}", env.difficulty);
                    println!("   Stage: {}", env.curriculum_stage);
                    println!();
                } else {
                    println!("{}", env.name);
                }
            }
        } else {
            missing += 1;
            missing_envs.push(env);

            if verbose {
                println!("{} ({}):", env.name, env.id);
                println!("   Expected path: {}", env.path);
                println!("   Full path: {}", full_path.display());
                println!("   Difficulty: {}", env.difficulty);
                println!("   Stage: {}", env.curriculum_stage);
                println!();
            } else {
                println!("{} - MISSING", env.name);
            }
        }
    }

    println!("\n📊 Summary:");
    println!("   Total environments: {}", total);
    println!(
        "   ✅ Implemented: {} ({:.1}%)",
        implemented,
        (implemented as f64 / total as f64) * 100.0
    );
    println!(
        "   ❌ Missing: {} ({:.1}%)",
        missing,
        (missing as f64 / total as f64) * 100.0
    );

    if missing > 0 {
        println!("\n⚠️  Missing Environments:");
        for env in &missing_envs {
            println!("{} ({})", env.name, env.id);
            if verbose {
                println!("     Path: {}", env.path);
                println!("     Tags: {}", env.tags.join(", "));
            }
        }

        println!("\n💡 To implement missing environments:");
        println!("   1. Create directory: packages/simulation/environments/robot-tasks/<path>");
        println!("   2. Add .tscn scene file");
        println!("   3. Add .gd script with environment logic");
        println!("   4. Add README.md documentation");
    } else {
        println!("\n✨ All catalog environments are implemented!");
    }

    Ok(())
}