# Shell Command Handlers
# Domain: Nushell environment, shell info, and resource listing

# REMOVED: use ../../../lib_provisioning * - causes circular import
use ../../flags.nu *

# Validate infrastructure name is safe from path injection
def validate_infra_name [infra: string] {
    # Returns true if INVALID (contains dangerous patterns)
    if ($infra | str contains "/") or ($infra | str contains "..") or ($infra | str starts-with "/") or ($infra | str contains " ") {
        return true
    }
    false
}

# Nu shell command handler - Start Nushell with provisioning library loaded
export def handle_nu [ops: string, flags: record] {
    let run_ops = if ($ops | str trim | str starts-with "-") {
        ""
    } else {
        let parts = ($ops | split row " ")
        if ($parts | is-empty) { "" } else { $parts | first }
    }

    if ($flags.infra | is-not-empty) {
        # Validate infra name to prevent path injection
        if (validate_infra_name $flags.infra) {
            error make { msg: "Invalid infrastructure name - contains path traversal characters" }
        }
        if ($env.PROVISIONING_INFRA_PATH | path join $flags.infra | path exists) {
            cd ($env.PROVISIONING_INFRA_PATH | path join $flags.infra)
        }
    }

    if ($flags.output_format | is-empty) {
        if ($run_ops | is-empty) {
            print (
                $"\nTo exit (_ansi purple_bold)NuShell(_ansi reset) session, with (_ansi default_dimmed)lib_provisioning(_ansi reset) loaded, " +
                $"use (_ansi green_bold)exit(_ansi reset) or (_ansi green_bold)[CTRL-D](_ansi reset)"
            )
            # Pass the provisioning configuration files to the Nu subprocess
            # This ensures the interactive session has the same config loaded as the calling environment
            let config_path = ($env.PROVISIONING_CONFIG? | default "")
            # Build library paths argument - needed for module resolution during parsing
            # Convert colon-separated string to -I flag arguments
            let lib_dirs = ($env.NU_LIB_DIRS? | default "")
            let lib_paths = if ($lib_dirs | is-not-empty) {
                ($lib_dirs | split row ":" | where { |x| ($x | is-not-empty) })
            } else {
                []
            }

            if ($config_path | is-not-empty) {
                # Pass config files AND library paths via -I flags for module resolution
                # Library paths are set via -I flags which enables module resolution during parsing phase
                if ($lib_paths | length) > 0 {
                    # Construct command with -I flags for each library path
                    let cmd = (mut cmd_parts = []; for path in $lib_paths { $cmd_parts = ($cmd_parts | append "-I" | append $path) }; $cmd_parts)
                    # Start interactive Nushell with provisioning configuration loaded
                    # The -i flag enables interactive mode (REPL) with full terminal features
                    ^nu --config $"($config_path)/config.nu" --env-config $"($config_path)/env.nu" ...$cmd -i
                } else {
                    ^nu --config $"($config_path)/config.nu" --env-config $"($config_path)/env.nu" -i
                }
            } else {
                # Fallback if PROVISIONING_CONFIG not set
                if ($lib_paths | length) > 0 {
                    let cmd = (mut cmd_parts = []; for path in $lib_paths { $cmd_parts = ($cmd_parts | append "-I" | append $path) }; $cmd_parts)
                    ^nu ...$cmd -i
                } else {
                    ^nu -i
                }
            }
        } else {
            # Also pass library paths for single command execution
            let lib_dirs = ($env.NU_LIB_DIRS? | default "")
            let lib_paths = if ($lib_dirs | is-not-empty) {
                ($lib_dirs | split row ":" | where { |x| ($x | is-not-empty) })
            } else {
                []
            }

            if ($lib_paths | length) > 0 {
                let cmd = (mut cmd_parts = []; for path in $lib_paths { $cmd_parts = ($cmd_parts | append "-I" | append $path) }; $cmd_parts)
                ^nu ...$cmd -c $"($run_ops)"
            } else {
                ^nu -c $"($run_ops)"
            }
        }
    }
}

# Nu info command handler - Show Nushell version info
export def handle_nuinfo [] {
    print $"\n (_ansi yellow)Nu shell info(_ansi reset)"
    print (version)
}

# List command handler - List resources (servers, taskservs, clusters)
export def handle_list [ops: string, flags: record] {
    let target_list = if ($ops | is-not-empty) {
        let parts = ($ops | split row " ")
        if ($parts | is-empty) { "" } else { $parts | first }
    } else { "" }

    let list_ops = ($ops | str replace $"($target_list) " "" | str trim)
    on_list $target_list ($flags.onsel | default "") $list_ops
}
