#!/usr/bin/env nu

# Enhanced Module Loader CLI
# Unified CLI for discovering and loading taskservs, providers, and clusters
# Includes template and layer support from enhanced version

use ../nulib/taskservs/discover.nu *
use ../nulib/taskservs/load.nu *
use ../nulib/providers/discover.nu *
use ../nulib/providers/load.nu *
use ../nulib/clusters/discover.nu *
use ../nulib/clusters/load.nu *
use ../nulib/lib_provisioning/module_loader.nu *
use ../nulib/lib_provisioning/config/accessor.nu config-get

# Main module loader command with enhanced features
def main [subcommand?: string] {
    if ($subcommand | is-empty) {
        print_enhanced_help
        return
    }

    match $subcommand {
        "help" => print_enhanced_help
        "discover" => print_discover_help
        "load" => print_load_help
        "list" => print_list_help
        "unload" => print_unload_help
        "init" => print_init_help
        "validate" => print_validate_help
        "info" => print_info_help
        "template" => print_template_help
        "layer" => print_layer_help
        "override" => print_override_help
        _ => {
            print $"Unknown command: ($subcommand)"
            print_enhanced_help
        }
    }
}

# === DISCOVERY COMMANDS ===

# Discover available modules
export def "main discover" [
    type: string,              # Module type: taskservs, providers, clusters
    query?: string,            # Search query
    --format: string = "table", # Output format: table, yaml, json, names
    --category: string = "",   # Filter by category (for taskservs)
    --group: string = ""       # Filter by group (for taskservs)
] {
    match $type {
        "taskservs" => {
            let taskservs = if ($query | is-empty) {
                discover-taskservs
            } else {
                search-taskservs $query
            }

            let filtered = if ($category | is-empty) and ($group | is-empty) {
                $taskservs
            } else if not ($category | is-empty) {
                $taskservs | where group == $category
            } else if not ($group | is-empty) {
                $taskservs | where group == $group
            } else {
                $taskservs
            }

            format_output $filtered $format
        }
        "providers" => {
            print "Provider discovery not implemented yet"
        }
        "clusters" => {
            print "Cluster discovery not implemented yet"
        }
        _ => {
            print $"Unknown module type: ($type)"
            print "Available types: taskservs, providers, clusters"
        }
    }
}

# Sync Nickel dependencies for infrastructure workspace
export def "main sync" [
    infra: string,                    # Infrastructure name or path
    --manifest: string = "providers.manifest.yaml",  # Manifest file name
    --show-modules                    # Show module info after sync
] {
    # Resolve infrastructure path
    let infra_path = if ($infra | path exists) {
        $infra
    } else {
        # Try workspace path
        let workspace_path = $"workspace/infra/($infra)"
        if ($workspace_path | path exists) {
            $workspace_path
        } else {
            print $"❌ Infrastructure not found: ($infra)"
            return
        }
    }

    # Sync Nickel dependencies using library function
    sync-nickel-dependencies $infra_path --manifest $manifest

    # Show Nickel module info if requested
    if $show_modules {
        print ""
        print "📋 Nickel Modules:"
        let modules_dir = (get-config-value "nickel" "modules_dir")
        let modules_path = ($infra_path | path join $modules_dir)

        if ($modules_path | path exists) {
            ls $modules_path | each {|entry|
                print $"  • ($entry.name | path basename) → ($entry.name)"
            }
        }
    }
}

# === LOAD/UNLOAD COMMANDS ===

# Load modules into workspace
export def "main load" [
    type: string,              # Module type: taskservs, providers, clusters
    workspace: string,         # Workspace path
    ...modules: string,        # Module names to load
    --layer: string = "workspace", # Layer to load into: workspace, infra
    --validate             # Validate after loading
    --force (-f)           # Force overwrite existing files
] {
    if ($modules | is-empty) {
        print $"No modules specified for loading"
        return
    }

    print $"Loading ($modules | length) ($type) into ($workspace) at layer ($layer)"

    match $type {
        "taskservs" | "providers" | "clusters" | "workflows" => {
            load_extension_to_workspace $type $workspace $modules $layer $force
        }
        _ => {
            print $"Unknown module type: ($type)"
        }
    }

    if $validate {
        main validate $workspace
    }
}

# Enhanced load with template support
export def "main load enhanced" [
    type: string,              # Module type
    workspace: string,         # Workspace path
    infra: string,             # Infrastructure name
    modules: list<string>,     # Module names
    --layer: string = "workspace", # Target layer
    --template-base        # Use template as base
] {
    print $"🚀 Enhanced loading ($modules | length) ($type) for infra ($infra)"

    for module in $modules {
        print $"  📦 Loading ($module)..."

        # Check if template exists for this module
        let template_path = $"provisioning/workspace/templates/taskservs/*/($module).k"
        let has_template = (glob $template_path | length) > 0

        if $has_template and $template_base {
            print $"    ✓ Using template base for ($module)"
            # Template-based loading would go here
        } else {
            print $"    ✓ Direct loading for ($module)"
            # Direct loading
        }
    }

    print "✅ Enhanced loading completed"
}

# Unload module from workspace
export def "main unload" [
    type: string,              # Module type
    workspace: string,         # Workspace path
    module: string,            # Module name to unload
    --layer: string = "workspace" # Layer to unload from
] {
    print $"Unloading ($module) from ($workspace) at layer ($layer)"

    match $type {
        "taskservs" => {
            unload_taskserv_from_workspace $workspace $module $layer
        }
        "providers" => {
            print "Provider unloading not implemented yet"
        }
        "clusters" => {
            print "Cluster unloading not implemented yet"
        }
        _ => {
            print $"Unknown module type: ($type)"
        }
    }
}

# === LIST COMMANDS ===

# List modules in workspace
export def "main list" [
    type: string,              # Module type
    workspace: string,         # Workspace path
    --layer: string = "all",   # Layer to list: workspace, infra, all
    --format: string = "table" # Output format
] {
    print $"Listing ($type) in ($workspace) for layer ($layer)"

    match $type {
        "taskservs" => {
            list_workspace_taskservs $workspace $layer $format
        }
        "providers" => {
            print "Provider listing not implemented yet"
        }
        "clusters" => {
            print "Cluster listing not implemented yet"
        }
        _ => {
            print $"Unknown module type: ($type)"
        }
    }
}

# === TEMPLATE COMMANDS ===

# List available templates
export def "main template list" [
    --template-type: string = "all",    # Template type: taskservs, providers, servers, clusters
    --format: string = "table" # Output format
] {
    print $"📋 Available templates type: ($template_type)"

    let template_base = "provisioning/workspace/templates"

    match $template_type {
        "taskservs" | "all" => {
            let taskserv_templates = if (($template_base | path join "taskservs") | path exists) {
                glob ($template_base | path join "taskservs" "*" "*.k")
                | each { |path|
                    let category = ($path | path dirname | path basename)
                    let name = ($path | path basename | str replace ".k" "")
                    { type: "taskserv", category: $category, name: $name, path: $path }
                }
            } else { [] }

            format_output $taskserv_templates $format
        }
        "providers" => {
            print "Provider templates not implemented yet"
        }
        "servers" => {
            let server_templates = if (($template_base | path join "servers") | path exists) {
                ls ($template_base | path join "servers") | get name
                | each { |path| { type: "server", name: ($path | path basename), path: $path } }
            } else { [] }

            format_output $server_templates $format
        }
        _ => {
            print $"Unknown template type: ($template_type)"
        }
    }
}

# Extract template from existing infrastructure
export def "main template extract" [
    source_infra: string,      # Source infrastructure path
    template_name: string,     # Name for the new template
    --type: string = "taskserv", # Template type
    --output: string = "provisioning/workspace/templates" # Output directory
] {
    print $"📤 Extracting template ($template_name) from ($source_infra)"

    # Implementation would analyze the source infra and create template
    print "Template extraction not yet implemented"
}

# Apply template to infrastructure
export def "main template apply" [
    template_name: string,     # Template to apply
    target_infra: string,      # Target infrastructure
    --override-file: string = "", # Override file path
    --dry-run              # Show what would be done
] {
    if $dry_run {
        print $"🔍 [DRY RUN] Would apply template ($template_name) to ($target_infra)"
    } else {
        print $"📥 Applying template ($template_name) to ($target_infra)"
    }

    # Implementation would apply template with overrides
    print "Template application not yet implemented"
}

# === LAYER COMMANDS ===

# Show layer information
export def "main layer show" [
    workspace: string,         # Workspace path
    --module: string = "",     # Specific module to show
    --type: string = "taskservs" # Module type
] {
    print $"📊 Layer information for ($workspace)"

    if not ($module | is-empty) {
        # Use existing layer utilities
        try {
            nu -c $"use provisioning/workspace/tools/layer-utils.nu *; test_layer_resolution ($module) ($workspace) upcloud"
        } catch {
            print $"Could not test layer resolution for ($module)"
        }
    } else {
        print "Showing overall layer structure..."
        try {
            nu -c "use provisioning/workspace/tools/layer-utils.nu *; show_layer_stats"
        } catch {
            print "Could not show layer statistics"
        }
    }
}

# Test layer resolution
export def "main layer test" [
    module: string,            # Module to test
    workspace: string,         # Workspace/infra name
    provider: string = "upcloud" # Provider for testing
] {
    print $"🧪 Testing layer resolution: ($module) in ($workspace) with ($provider)"

    try {
        nu -c $"use provisioning/workspace/tools/layer-utils.nu *; test_layer_resolution ($module) ($workspace) ($provider)"
    } catch {
        print $"❌ Layer resolution test failed for ($module)"
    }
}

# === OVERRIDE COMMANDS ===

# Create configuration override
export def "main override create" [
    type: string,              # Type: taskservs, providers, clusters
    infra: string,             # Infrastructure name
    module: string,            # Module name
    --from: string = "",       # Template to base override on
    --layer: string = "infra"  # Layer for override
] {
    print $"⚙️  Creating override for ($module) in ($infra) at layer ($layer)"

    let override_path = match $layer {
        "infra" => $"workspace/infra/($infra)/overrides/($module).k"
        "workspace" => $"provisioning/workspace/templates/($type)/($module).k"
        _ => {
            print $"Unknown layer: ($layer)"
            return
        }
    }

    print $"📝 Override will be created at: ($override_path)"

    if not ($from | is-empty) {
        print $"📋 Based on template: ($from)"
    }

    # Create directory if needed
    mkdir ($override_path | path dirname)

    # Create basic override file
    let content = if not ($from | is-empty) {
        $"# Override for ($module) in ($infra)
# Based on template: ($from)

import ($type).*.($module).ncl.($module) as base
import provisioning.workspace.templates.($type).($from) as template

# Infrastructure-specific overrides
($module)_($infra)_override: base.($module | str capitalize) = template.($from)_template {
    # Add your overrides here
    # Example:
    # replicas = 3
    # resources.memory = \"1Gi\"
}
"
    } else {
        $"# Override for ($module) in ($infra)

import ($type).*.($module).ncl.($module) as base

# Infrastructure-specific overrides
($module)_($infra)_override: base.($module | str capitalize) = base.($module)_config {
    # Add your overrides here
    # Example:
    # replicas = 3
    # resources.memory = \"1Gi\"
}
"
    }

    $content | save $override_path
    print $"✅ Override created: ($override_path)"
}

# === WORKSPACE MANAGEMENT ===

# Initialize workspace with modules
export def "main init" [
    workspace: string,         # Workspace path
    --modules: list<string> = [], # Initial modules to load
    --template: string = "",   # Workspace template
    --provider: string = "upcloud" # Default provider
] {
    print $"🚀 Initializing workspace: ($workspace)"

    # Create workspace structure
    let workspace_dirs = [
        $"($workspace)/config"
        $"($workspace)/taskservs"
        $"($workspace)/overrides"
        $"($workspace)/defs"
        $"($workspace)/clusters"
    ]

    for dir in $workspace_dirs {
        mkdir $dir
        print $"  📁 Created: ($dir)"
    }

    # Create basic configuration
    let config_content = $"# Workspace configuration for ($workspace)
# Provider: ($provider)
# Initialized: (date now)

provider = "($provider)"
workspace = "($workspace)"
"
    $config_content | save $"($workspace)/config/workspace.toml"
    print $"  📄 Created: ($workspace)/config/workspace.toml"

    # Load initial modules
    if ($modules | length) > 0 {
        print $"📦 Loading initial modules: (($modules | str join ', '))"
        main load taskservs $workspace ...$modules
    }

    print $"✅ Workspace ($workspace) initialized successfully"
}

# Validate workspace integrity
export def "main validate" [workspace: string] {
    print $"🔍 Validating workspace: ($workspace)"

    let required_dirs = ["config", "taskservs", "overrides", "defs"]
    mut validation_errors = []

    for dir in $required_dirs {
        let full_path = ($workspace | path join $dir)
        if not ($full_path | path exists) {
            $validation_errors = ($validation_errors | append $"Missing directory: ($full_path)")
        }
    }

    # Check configuration file
    let config_file = ($workspace | path join "config" "workspace.toml")
    if not ($config_file | path exists) {
        $validation_errors = ($validation_errors | append $"Missing configuration: ($config_file)")
    }

    # Report results
    if ($validation_errors | is-empty) {
        print "✅ Workspace validation passed"
        return true
    } else {
        print "❌ Workspace validation failed:"
        for error in $validation_errors {
            print $"  • ($error)"
        }
        return false
    }
}

# Show workspace information
export def "main info" [workspace: string] {
    print $"📊 Workspace Information: ($workspace)"

    if not (($workspace | path join "config" "workspace.toml") | path exists) {
        print "❌ Workspace not found or not initialized"
        return
    }

    # Show basic info
    let config = try { open ($workspace | path join "config" "workspace.toml") | from toml } catch { {} }

    print $"  Provider: (($config.provider? | default 'unknown'))"
    print $"  Path: ($workspace)"

    # Count modules
    let taskserv_count = try {
        ls ($workspace | path join "taskservs") | length
    } catch { 0 }

    let override_count = try {
        ls ($workspace | path join "overrides") | length
    } catch { 0 }

    print $"  Task Services: ($taskserv_count)"
    print $"  Overrides: ($override_count)"

    # Show recent activity
    let recent_files = try {
        ls $workspace | where type == file | sort-by modified | last 3 | get name
    } catch { [] }

    if ($recent_files | length) > 0 {
        print "  Recent activity:"
        for file in $recent_files {
            print $"    • ($file | path basename)"
        }
    }
}

# === HELPER FUNCTIONS ===

# Generic extension loading function (taskservs, providers, clusters, workflows)
def load_extension_to_workspace [
    extension_type: string,  # taskservs, providers, clusters, workflows
    workspace: string,
    modules: list<string>,
    layer: string,
    force: bool = false
] {
    # Get extension-specific info function based on type
    let get_info_fn = match $extension_type {
        "taskservs" => { |name| get-taskserv-info $name }
        "providers" => { |name| get-provider-info $name }
        "clusters" => { |name| get-cluster-info $name }
        _ => { |name| {name: $name, group: "", type: $extension_type} }
    }

    # Get source path from config
    let source_base_path = (config-get $"paths.($extension_type)" | path expand)

    # Get template base path from config
    let provisioning_base = (config-get "paths.base" | path expand)
    let template_base_path = ($provisioning_base | path join "workspace" "templates" $extension_type)

    for module in $modules {
        print $"  📦 Loading ($extension_type): ($module)"

        # Get module info
        let module_info = try {
            do $get_info_fn $module
        } catch {
            print $"    ❌ Module not found: ($module)"
            continue
        }

        print $"    ✓ Found: ($module_info.name) (($module_info.group? | default ""))"

        # Resolve workspace paths
        let workspace_abs = ($workspace | path expand)
        let workspace_root = if ($workspace_abs | str contains "/infra/") {
            let parts = ($workspace_abs | split row "/infra/")
            $parts.0
        } else {
            $workspace_abs
        }

        # Build source path (handle optional group, "root" means no category)
        let group_path = ($module_info.group? | default "")
        let group_path = if ($group_path == "root") { "" } else { $group_path }
        let source_module_path = if ($group_path | is-not-empty) {
            $source_base_path | path join $group_path $module
        } else {
            $source_base_path | path join $module
        }

        # STEP 1: Copy schemas to workspace/.{extension_type}
        let target_schemas_dir = ($workspace_root | path join $".($extension_type)")
        let target_module_path = if ($group_path | is-not-empty) {
            $target_schemas_dir | path join $group_path $module
        } else {
            $target_schemas_dir | path join $module
        }

        # Config file directory
        let config_dir = ($workspace_abs | path join $extension_type)
        let config_file_path = ($config_dir | path join $"($module).k")

        # Check if already loaded
        if ($config_file_path | path exists) and ($target_module_path | path exists) {
            if not $force {
                print $"    ✅ Module already loaded: ($module)"
                print $"       Config: ($config_file_path)"
                print $"       Source: ($target_module_path)"
                print $"       💡 Use --force to overwrite existing files"
                continue
            } else {
                print $"    🔄 Overwriting existing module: ($module)"
            }
        }

        # Copy schemas from system extensions to workspace
        let parent_dir = ($target_module_path | path dirname)
        mkdir $parent_dir

        if ($source_module_path | path exists) {
            print $"    📦 Copying schemas to workspace .($extension_type)..."
            print $"       From: ($source_module_path)"
            print $"       To: ($target_module_path)"

            if ($target_module_path | path exists) {
                rm -rf $target_module_path
            }

            cp -r $source_module_path $parent_dir
            print $"    ✓ Schemas copied to workspace .($extension_type)/"

            # STEP 2a: Update individual module's nickel.mod with correct workspace paths
            # Calculate relative paths based on categorization depth
            let provisioning_path = if ($group_path | is-not-empty) {
                # Categorized: .{ext}/{category}/{module}/nickel/ -> ../../../../.nickel/packages/provisioning
                "../../../../.nickel/packages/provisioning"
            } else {
                # Non-categorized: .{ext}/{module}/nickel/ -> ../../../.nickel/packages/provisioning
                "../../../.nickel/packages/provisioning"
            }

            let parent_path = if ($group_path | is-not-empty) {
                # Categorized: .{ext}/{category}/{module}/nickel/ -> ../../..
                "../../.."
            } else {
                # Non-categorized: .{ext}/{module}/nickel/ -> ../..
                "../.."
            }

            # Update the module's nickel.mod file with workspace-relative paths
            let module_nickel_mod_path = ($target_module_path | path join "nickel" "nickel.mod")
            if ($module_nickel_mod_path | path exists) {
                print $"    🔧 Updating module nickel.mod with workspace paths"
                let module_nickel_mod_content = $"[package]
name = \"($module)\"
edition = \"v0.11.3\"
version = \"0.0.1\"

[dependencies]
provisioning = { path = \"($provisioning_path)\", version = \"0.0.1\" }
($extension_type) = { path = \"($parent_path)\", version = \"0.1.0\" }
"
                $module_nickel_mod_content | save -f $module_nickel_mod_path
                print $"    ✓ Updated nickel.mod: ($module_nickel_mod_path)"
            }
        } else {
            print $"    ⚠️  Warning: Source not found at ($source_module_path)"
        }

        # STEP 2b: Create nickel.mod in workspace/.{extension_type}
        let extension_nickel_mod = ($target_schemas_dir | path join "nickel.mod")
        if not ($extension_nickel_mod | path exists) {
            print $"    📦 Creating nickel.mod for .($extension_type) package"
            let nickel_mod_content = $"[package]
name = \"($extension_type)\"
edition = \"v0.11.3\"
version = \"0.1.0\"
description = \"Workspace-level ($extension_type) schemas\"
"
            $nickel_mod_content | save $extension_nickel_mod
        }

        # Ensure config directory exists
        mkdir $config_dir

        # STEP 4: Generate config from template
        let template_path = if ($group_path | is-not-empty) {
            $template_base_path | path join $group_path $"($module).k"
        } else {
            $template_base_path | path join $"($module).k"
        }

        # Build import statement with "as {module}" alias
        let import_stmt = if ($group_path | is-not-empty) {
            $"import ($extension_type).($group_path).($module).ncl.($module) as ($module)"
        } else {
            $"import ($extension_type).($module).ncl.($module) as ($module)"
        }

        # Get relative paths for comments
        let workspace_name = ($workspace_root | path basename)
        let relative_schema_path = if ($group_path | is-not-empty) {
            $"($workspace_name)/.($extension_type)/($group_path)/($module)"
        } else {
            $"($workspace_name)/.($extension_type)/($module)"
        }

        let config_content = if ($template_path | path exists) {
            print $"    📄 Using template from: ($template_path)"
            let template_body = (open $template_path)
            $"# Configuration for ($module)
# Workspace: ($workspace_name)
# Schemas from: ($relative_schema_path)
($import_stmt)

($template_body)"
        } else {
            $"# Configuration for ($module)
# Workspace: ($workspace_name)
# Schemas from: ($relative_schema_path)
($import_stmt)

# TODO: Configure your ($module) instance
# See available schemas at: ($relative_schema_path)/nickel/
"
        }

        $config_content | save -f $config_file_path
        print $"    ✓ Config created: ($config_file_path)"
        print $"       📝 Edit ($extension_type)/($module).k to configure settings"

        # STEP 3: Update infra nickel.mod
        if ($workspace_abs | str contains "/infra/") {
            let nickel_mod_path = ($workspace_abs | path join "nickel.mod")
            if ($nickel_mod_path | path exists) {
                let nickel_mod_content = (open $nickel_mod_path)
                if not ($nickel_mod_content | str contains $"($extension_type) =") {
                    print $"    🔧 Updating nickel.mod to include ($extension_type) dependency"
                    let new_dependency = $"\n# Workspace-level ($extension_type) \(shared across infras\)\n($extension_type) = { path = \"../../.($extension_type)\" }\n"
                    $"($nickel_mod_content)($new_dependency)" | save -f $nickel_mod_path
                }
            }
        }
    }
}

# Unload taskserv from workspace
def unload_taskserv_from_workspace [workspace: string, module: string, layer: string] {
    let target_path = match $layer {
        "workspace" => ($workspace | path join "taskservs" $"($module).k")
        "infra" => ($workspace | path join "overrides" $"($module).k")
        _ => ($workspace | path join "taskservs" $"($module).k")
    }

    if ($target_path | path exists) {
        rm $target_path
        print $"  ✓ Removed: ($target_path)"
    } else {
        print $"  ❌ Not found: ($target_path)"
    }
}

# List workspace taskservs
def list_workspace_taskservs [workspace: string, layer: string, format: string] {
    let paths = match $layer {
        "workspace" => [($workspace | path join "taskservs")]
        "infra" => [($workspace | path join "overrides")]
        "all" => [($workspace | path join "taskservs"), ($workspace | path join "overrides")]
        _ => [($workspace | path join "taskservs")]
    }

    mut all_taskservs = []

    for path in $paths {
        if ($path | path exists) {
            let taskservs = ls $path
            | where type == file
            | where name =~ '\\.k$'
            | each { |file|
                {
                    name: ($file.name | path basename | str replace ".k" "")
                    layer: ($path | path basename)
                    path: $file.name
                    modified: $file.modified
                }
            }
            $all_taskservs = ($all_taskservs | append $taskservs)
        }
    }

    format_output $all_taskservs $format
}

# Format output based on requested format
def format_output [data: any, format: string] {
    match $format {
        "json" => ($data | to json)
        "yaml" => ($data | to yaml)
        "names" => ($data | get name | str join "\n")
        "table" | _ => ($data | table)
    }
}

# === HELP FUNCTIONS ===

def print_enhanced_help [] {
    print "Enhanced Module Loader CLI - Discovery and loading with template support"
    print ""
    print "Usage: module-loader <command> [options]"
    print ""
    print "CORE COMMANDS:"
    print "  discover <type> [query] [--format <fmt>] [--category <cat>] - Discover available modules"
    print "  sync <infra> [--manifest <file>] [--show-modules]          - Sync Nickel dependencies for infrastructure"
    print "  load <type> <workspace> <modules...> [--layer <layer>]     - Load modules into workspace"
    print "  list <type> <workspace> [--layer <layer>]                  - List loaded modules"
    print "  unload <type> <workspace> <module> [--layer <layer>]       - Unload module from workspace"
    print ""
    print "WORKSPACE COMMANDS:"
    print "  init <workspace> [--modules <list>] [--template <name>]    - Initialize workspace"
    print "  validate <workspace>                                       - Validate workspace integrity"
    print "  info <workspace>                                           - Show workspace information"
    print ""
    print "TEMPLATE COMMANDS:"
    print "  template list [--type <type>] [--format <fmt>]             - List available templates"
    print "  template extract <source> <name> [--type <type>]           - Extract template from infra"
    print "  template apply <template> <target> [--dry-run]             - Apply template to infra"
    print ""
    print "LAYER COMMANDS:"
    print "  layer show <workspace> [--module <name>]                   - Show layer information"
    print "  layer test <module> <workspace> [provider]                 - Test layer resolution"
    print ""
    print "OVERRIDE COMMANDS:"
    print "  override create <type> <infra> <module> [--from <template>] - Create configuration override"
    print ""
    print "ENHANCED COMMANDS:"
    print "  load enhanced <type> <workspace> <infra> <modules> [--layer <layer>] - Enhanced template loading"
    print ""
    print "Types: taskservs, providers, clusters"
    print "Layers: workspace, infra, all"
    print "Formats: table, json, yaml, names"
    print ""
    print "Examples:"
    print "  module-loader discover taskservs --category databases"
    print "  module-loader load taskservs ./workspace [redis, postgres]"
    print "  module-loader template list --type taskservs"
    print "  module-loader layer test redis wuji upcloud"
    print "  module-loader override create taskservs wuji kubernetes --from ha-cluster"
}

def print_discover_help [] {
    print "Discover available modules"
    print ""
    print "Usage: module-loader discover <type> [query] [options]"
    print ""
    print "Options:"
    print "  --format <fmt>     Output format: table, json, yaml, names (default: table)"
    print "  --category <cat>   Filter by category (taskservs only)"
    print "  --group <group>    Filter by group (taskservs only)"
    print ""
    print "Examples:"
    print "  module-loader discover taskservs"
    print "  module-loader discover taskservs redis"
    print "  module-loader discover taskservs --category databases"
    print "  module-loader discover taskservs --format json"
}

def print_load_help [] {
    print "Load modules into workspace"
    print ""
    print "Usage: module-loader load <type> <workspace> <modules...> [options]"
    print ""
    print "Options:"
    print "  --layer <layer>    Target layer: workspace, infra (default: workspace)"
    print "  --validate         Validate workspace after loading"
    print ""
    print "Examples:"
    print "  module-loader load taskservs ./workspace [kubernetes, cilium]"
    print "  module-loader load taskservs ./workspace [redis] --layer infra"
}

def print_list_help [] {
    print "List modules in workspace"
    print ""
    print "Usage: module-loader list <type> <workspace> [options]"
    print ""
    print "Options:"
    print "  --layer <layer>    Layer to list: workspace, infra, all (default: all)"
    print "  --format <fmt>     Output format: table, json, yaml, names"
    print ""
    print "Examples:"
    print "  module-loader list taskservs ./workspace"
    print "  module-loader list taskservs ./workspace --layer workspace"
}

def print_unload_help [] {
    print "Unload module from workspace"
    print ""
    print "Usage: module-loader unload <type> <workspace> <module> [options]"
    print ""
    print "Options:"
    print "  --layer <layer>    Layer to unload from: workspace, infra (default: workspace)"
    print ""
    print "Examples:"
    print "  module-loader unload taskservs ./workspace kubernetes"
    print "  module-loader unload taskservs ./workspace redis --layer infra"
}

def print_init_help [] {
    print "Initialize workspace with modules"
    print ""
    print "Usage: module-loader init <workspace> [options]"
    print ""
    print "Options:"
    print "  --modules <list>   Initial modules to load"
    print "  --template <name>  Workspace template to use"
    print "  --provider <name>  Default provider (default: upcloud)"
    print ""
    print "Examples:"
    print "  module-loader init ./my-workspace"
    print "  module-loader init ./k8s-workspace --modules [kubernetes, cilium]"
}

def print_validate_help [] {
    print "Validate workspace integrity"
    print ""
    print "Usage: module-loader validate <workspace>"
    print ""
    print "Examples:"
    print "  module-loader validate ./workspace"
}

def print_info_help [] {
    print "Show workspace information"
    print ""
    print "Usage: module-loader info <workspace>"
    print ""
    print "Examples:"
    print "  module-loader info ./workspace"
}

def print_template_help [] {
    print "Template management commands"
    print ""
    print "Usage: module-loader template <subcommand> [options]"
    print ""
    print "Subcommands:"
    print "  list      List available templates"
    print "  extract   Extract template from existing infrastructure"
    print "  apply     Apply template to infrastructure"
    print ""
    print "Examples:"
    print "  module-loader template list --type taskservs"
    print "  module-loader template extract ./wuji wuji-production"
    print "  module-loader template apply wuji-production ./new-infra"
}

def print_layer_help [] {
    print "Layer resolution commands"
    print ""
    print "Usage: module-loader layer <subcommand> [options]"
    print ""
    print "Subcommands:"
    print "  show   Show layer information for workspace"
    print "  test   Test layer resolution for specific module"
    print ""
    print "Examples:"
    print "  module-loader layer show ./workspace"
    print "  module-loader layer test kubernetes wuji upcloud"
}

def print_override_help [] {
    print "Configuration override commands"
    print ""
    print "Usage: module-loader override create <type> <infra> <module> [options]"
    print ""
    print "Options:"
    print "  --from <template>  Base override on template"
    print "  --layer <layer>    Target layer: infra, workspace (default: infra)"
    print ""
    print "Examples:"
    print "  module-loader override create taskservs wuji kubernetes"
    print "  module-loader override create taskservs wuji redis --from databases/redis"
}
