#!/usr/bin/env nu
# [command]
# name = "metadata handler"
# group = "infrastructure"
# tags = ["metadata", "forms", "validation", "interactive"]
# version = "2.0.0"
# requires = ["traits.nu"]

# ============================================================================
# Metadata Handler for Dispatcher Integration
# Version: 2.0.0
# Purpose: Validate commands and execute interactive forms in dispatcher
# ============================================================================

use ../lib_provisioning/commands/traits.nu *

# Validate command exists and meets requirements
def validate-command-execution [
    canonical_name: string
    flags: record = {}
] : nothing -> record {
    let metadata_result = (get-command-metadata $canonical_name)

    # If metadata not found, allow command through with default settings
    # Metadata is optional - commands can still work without it
    if not $metadata_result.found {
        return {
            valid: true
            error: ""
            interactive: false
            form_template: ""
        }
    }

    let req = $metadata_result.metadata.requirements

    # Check workspace requirement
    if ($req.requires_workspace and (($env.PROVISIONING_WORKSPACE? | is-empty))) {
        if not ($flags.workspace? | is-empty) {
            # Workspace flag provided, will be set by dispatcher
        } else {
            return {
                valid: false
                error: "Active workspace required. Use --workspace <name> or set PROVISIONING_WORKSPACE"
                interactive: false
                form_template: ""
            }
        }
    }

    # Check confirmation requirement
    if ($req.requires_confirmation and not ($flags.auto_confirm? | default false)) {
        # Forms will handle this
    }

    # Check auth requirement
    if ($req.requires_auth) {
        # Auth will be validated by auth handler, not here
    }

    {
        valid: true
        error: ""
        interactive: $req.interactive
        form_template: ($metadata_result.metadata.form_path? // "")
        metadata: $metadata_result.metadata
    }
}

# Handle interactive command execution
def handle-interactive-command [
    canonical_name: string
    form_template: string
    form_context: record = {}
] : nothing -> record {
    # Determine which form to run based on command
    # Use specialized functions from their modules for setup and workspace
    let form_result = (
        match $canonical_name {
            "setup" => {
                use ../lib_provisioning/setup/wizard.nu *
                # For setup, we return a special handling marker
                # The dispatcher will handle calling the right function
                {
                    success: true
                    error: ""
                    values: {}
                    _setup_command: true
                }
            }
            "workspace init" => {
                # For workspace init, same approach
                {
                    success: true
                    error: ""
                    values: {}
                    _workspace_init_command: true
                }
            }
            "auth login" => { run-form $form_template }
            "server delete" => { run-form $form_template }
            _ => {
                if not (($form_template | is-empty)) {
                    run-form $form_template
                } else {
                    {
                        success: false
                        error: "No form template defined for interactive command"
                        values: {}
                    }
                }
            }
        }
    )

    if not $form_result.success {
        return {
            proceed: false
            error: $form_result.error
            form_values: {}
        }
    }

    # Inject form results into environment for command to use
    $env.FORM_RESULTS = ($form_result.values | to json)

    {
        proceed: true
        error: ""
        form_values: $form_result.values
    }
}

# Print validation errors
def show-validation-error [error_msg: string] : nothing -> nothing {
    print $"(ansi red_bold)✗ Command validation failed(ansi reset)"
    print $"  (ansi yellow)Error:(ansi reset) ($error_msg)"
    print ""
}

# Validate and prepare command for execution
def prepare-command-execution [
    canonical_name: string
    flags: record = {}
] : nothing -> record {
    # Validate command
    let validation = (validate-command-execution $canonical_name $flags)

    if not $validation.valid {
        show-validation-error $validation.error
        return {
            proceed: false
            error: $validation.error
            form_values: {}
        }
    }

    # Handle interactive commands
    if $validation.interactive {
        handle-interactive-command $canonical_name $validation.form_template {}
    } else {
        {
            proceed: true
            error: ""
            form_values: {}
        }
    }
}

# Check if command should skip if --yes flag provided
def should-skip-interactive [flags: record] : nothing -> bool {
    $flags.auto_confirm? | default false
}

# Main exported function for dispatcher integration
export def validate-and-prepare [
    command_str: string
    flags: record = {}
] : nothing -> record {
    # If --yes flag provided, skip interactive forms
    if (should-skip-interactive $flags) {
        return {
            proceed: true
            error: ""
            form_values: {}
        }
    }

    prepare-command-execution $command_str $flags
}
