#!/usr/bin/env bash
# Info: Script to run Provisioning
# Author: Jesus Perez Lorenzo
# Release: 3.0.11
# Date: 2026-01-14

set +o errexit
set +o pipefail

# Debug: log startup
[ "${PROVISIONING_DEBUG_STARTUP:-false}" = "true" ] && echo "[DEBUG] Wrapper started with args: $@" >&2

export NU=$(type -P nu)

_release() {
    grep "^# Release:" "$0" | sed "s/# Release: //g"
}

export PROVISIONING_VERS=$(_release)

set -o allexport
## shellcheck disable=SC1090
[ -n "$PROVISIONING_ENV" ] && [ -r "$PROVISIONING_ENV" ] && source "$PROVISIONING_ENV"
[ -r "../env-provisioning" ] && source ../env-provisioning
[ -r "env-provisioning" ] && source ./env-provisioning
#[ -r ".env" ] && source .env set

# Disable provisioning logo/banner output
export PROVISIONING_NO_TITLES=true

set +o allexport

export PROVISIONING=${PROVISIONING:-/usr/local/provisioning}
PROVIISONING_WKPATH=${PROVIISONING_WKPATH:-/tmp/tmp.}

RUNNER="provisioning"
PROVISIONING_MODULE=""
PROVISIONING_MODULE_TASK=""

# Safe argument handling - use default empty value if unbound
[ "${1:-}" == "" ] && shift

[ -z "$NU" ] || [ "${1:-}" == "install" ] || [ "${1:-}" == "reinstall" ] || [ "${1:-}" == "mode" ] && exec bash $PROVISIONING/core/bin/install_nu.sh $PROVISIONING ${1:-} ${2:-}

[ "${1:-}" == "rmwk" ] && rm -rf "$PROVIISONING_WKPATH"* && echo "$PROVIISONING_WKPATH deleted" && exit
[ "${1:-}" == "-x" ] && debug=-x && export PROVISIONING_DEBUG=true && shift
[ "${1:-}" == "-xm" ] && export PROVISIONING_METADATA=true && shift
[ "${1:-}" == "nu" ] && export PROVISIONING_DEBUG=true
[ "${1:-}" == "--x" ] && set -x && debug=-x && export PROVISIONING_DEBUG=true && shift
[ "${1:-}" == "-i" ] || [ "${2:-}" == "-i" ] && echo "$(basename "$0") $(grep "^# Info:" "$0" | sed "s/# Info: //g") " && exit
[ "${1:-}" == "-v" ] || [ "${1:-}" == "--version" ] || [ "${2:-}" == "-v" ] && _release && exit

# ════════════════════════════════════════════════════════════════════════════════
# FLOW-AWARE TTY COMMAND FILTER
# Manages three execution flows: exit (standalone), pipe (inter-command), continue (Nushell)
# Registry: provisioning/core/cli/tty-commands.conf
# Filter:   provisioning/core/cli/tty-filter.sh
# ════════════════════════════════════════════════════════════════════════════════
if [ -f "$PROVISIONING/core/cli/tty-filter.sh" ]; then
    # Source filter function
    # shellcheck source=/dev/null
    source "$PROVISIONING/core/cli/tty-filter.sh"

    # Try to filter TTY command (full command line as single string)
    # Return codes:
    #   - filter_tty_command returns 0: flow=continue case handled, continue to Nushell with $TTY_OUTPUT
    #   - filter_tty_command exits: flow=exit/pipe case completed (already exited)
    #   - filter returns 1: not a TTY command, continue to normal processing
    if filter_tty_command "$@"; then
        # Flow=continue: TTY wrapper executed, output in $TTY_OUTPUT, bypass daemon
        # $env.PROVISIONING_BYPASS_DAEMON and $env.TTY_OUTPUT available to Nushell
        : # Continue to Nushell dispatcher below
    fi
fi

CMD_ARGS=$@

# Note: Flag ordering is handled by Nushell's reorder_args function
# which automatically reorders flags before positional arguments.
# Flags can be placed anywhere on the command line.
case "${1:-}" in
# Note: "setup" is now handled by the main provisioning CLI dispatcher
# No special module handling needed
-mod)
    PROVISIONING_MODULE=$(echo "$2" | sed 's/ //g' | cut -f1 -d"|")
    PROVISIONING_MODULE_TASK=$(echo "$2" | sed 's/ //g' | cut -f2 -d"|")
    [ "$PROVISIONING_MODULE" == "$PROVISIONING_MODULE_TASK" ] && PROVISIONING_MODULE_TASK=""
    shift 2
    CMD_ARGS=$@
    [ "${PROVISIONING_DEBUG_STARTUP:-false}" = "true" ] && echo "[DEBUG] -mod detected: MODULE=$PROVISIONING_MODULE, TASK=$PROVISIONING_MODULE_TASK, CMD_ARGS=$CMD_ARGS" >&2
    ;;
esac
NU_ARGS=""

DEFAULT_CONTEXT_TEMPLATE="default_context.yaml"
case "$(uname | tr '[:upper:]' '[:lower:]')" in
linux)
    PROVISIONING_USER_CONFIG="$HOME/.config/provisioning/nushell"
    PROVISIONING_CONTEXT_PATH="$HOME/.config/provisioning/$DEFAULT_CONTEXT_TEMPLATE"
    PROVISIONING_USER_PLATFORM="$HOME/.config/provisioning/platform"
    ;;
darwin)
    PROVISIONING_USER_CONFIG="$HOME/Library/Application Support/provisioning/nushell"
    PROVISIONING_CONTEXT_PATH="$HOME/Library/Application Support/provisioning/$DEFAULT_CONTEXT_TEMPLATE"
    PROVISIONING_USER_PLATFORM="$HOME/Library/Application Support/provisioning/platform"
    ;;
*)
    PROVISIONING_USER_CONFIG="$HOME/.config/provisioning/nushell"
    PROVISIONING_CONTEXT_PATH="$HOME/.config/provisioning/$DEFAULT_CONTEXT_TEMPLATE"
    PROVISIONING_USER_PLATFORM="$HOME/.config/provisioning/platform"
    ;;
esac

# ════════════════════════════════════════════════════════════════════════════════
# DAEMON ROUTING - Try daemon for all commands (except setup/help/interactive)
# Falls back to traditional handlers if daemon unavailable
# ════════════════════════════════════════════════════════════════════════════════

DAEMON_ENDPOINT="http://127.0.0.1:9091/execute"

# Function to execute command via daemon
execute_via_daemon() {
    local cmd="$1"
    shift

    # Build JSON array of arguments (simple bash)
    local args_json="["
    local first=1
    for arg in "$@"; do
        [ $first -eq 0 ] && args_json="$args_json,"
        args_json="$args_json\"$(echo "$arg" | sed 's/"/\\"/g')\""
        first=0
    done
    args_json="$args_json]"

    # Determine timeout based on command type
    # Heavy commands (create, delete, update) get longer timeout
    local timeout=0.5
    case "$cmd" in
    create | delete | update | setup | init) timeout=5 ;;
    *) timeout=0.2 ;;
    esac

    # Make request and extract stdout
    curl -s -m $timeout -X POST "$DAEMON_ENDPOINT" \
        -H "Content-Type: application/json" \
        -d "{\"command\":\"$cmd\",\"args\":$args_json,\"timeout_ms\":30000}" 2>/dev/null |
        sed -n 's/.*"stdout":"\(.*\)","execution.*/\1/p' |
        sed 's/\\n/\n/g'
}

# Try daemon ONLY for lightweight commands (list, show, status)
# Skip daemon for heavy commands (create, delete, update) because bash wrapper is slow
# ALSO skip daemon for flow=continue commands (need stdin for TTY interaction)
if [ "${PROVISIONING_BYPASS_DAEMON:-}" != "true" ] && ([ "${1:-}" = "server" ] || [ "${1:-}" = "s" ]); then
    if [ "${2:-}" = "list" ] || [ -z "${2:-}" ]; then
        # Light command - try daemon
        [ -n "${PROVISIONING_DEBUG:-}" ] && [ "${PROVISIONING_DEBUG:-}" = "true" ] && echo "⚡ Attempting daemon execution..." >&2
        DAEMON_OUTPUT=$(execute_via_daemon "$@" 2>/dev/null)
        if [ -n "$DAEMON_OUTPUT" ]; then
            echo "$DAEMON_OUTPUT"
            exit 0
        fi
        [ -n "${PROVISIONING_DEBUG:-}" ] && [ "${PROVISIONING_DEBUG:-}" = "true" ] && echo "⚠️ Daemon unavailable, using traditional handlers..." >&2
    fi
    # NOTE: Command reordering (server create -> create server) has been removed.
    # The Nushell dispatcher in provisioning/core/nulib/main_provisioning/dispatcher.nu
    # handles command routing correctly and expects "server create" format.
    # The reorder_args function in provisioning script handles any flag reordering needed.
fi

# ════════════════════════════════════════════════════════════════════════════════
# FAST-PATH: Commands that don't need full config loading or platform bootstrap
# These commands use lib_minimal.nu for <100ms execution
# (ONLY REACHED if daemon is not available)
# ═══���════════════════════════════════════════════════════════════════════════════

# Help commands fast-path (uses help_minimal.nu)
# Detects "help" in ANY argument position, not just first
help_category=""
help_found=false

# Check if first arg is empty (no args provided) - treat as help request
if [ -z "${1:-}" ]; then
    help_found=true
else
    # Loop through all arguments to find help variant and extract category
    for arg in "$@"; do
        case "$arg" in
        help|-h|--help|--helpinfo)
            help_found=true
            ;;
        -*)
            # Skip flags (like -x, -xm, -i, -v, etc.)
            ;;
        *)
            # First non-flag, non-help argument becomes the category
            if [ "$help_category" = "" ]; then
                help_category="$arg"
            fi
            ;;
        esac
    done
fi

# Execute help fast-path if help was requested
if [ "$help_found" = true ]; then
    # Export LANG explicitly to ensure locale detection works in nu subprocess
    export LANG
    $NU -n -c "source '$PROVISIONING/core/nulib/help_minimal.nu'; provisioning-help '$help_category' | print" 2>/dev/null
    exit $?
fi

# Workspace operations (fast-path)
if [ "${1:-}" = "workspace" ] || [ "${1:-}" = "ws" ]; then
    case "${2:-}" in
    "list" | "")
        $NU -n -c "source '$PROVISIONING/core/nulib/lib_minimal.nu'; workspace-list | get ok | table" 2>/dev/null
        exit $?
        ;;
    "active")
        $NU -n -c "source '$PROVISIONING/core/nulib/lib_minimal.nu'; workspace-active" 2>/dev/null
        exit $?
        ;;
    "info")
        if [ -n "${3:-}" ]; then
            $NU -n -c "source '$PROVISIONING/core/nulib/lib_minimal.nu'; workspace-info '$3'" 2>/dev/null
        else
            $NU -n -c "source '$PROVISIONING/core/nulib/lib_minimal.nu'; workspace-active | workspace-info \$in" 2>/dev/null
        fi
        exit $?
        ;;
    esac
    # Other workspace commands (switch, register, etc.) fall through to full loading
fi

# Status/Health check (fast-path) - DISABLED to fix dispatcher loop
# Use normal dispatcher path instead of fast-path with lib_minimal.nu
# if [ "$1" = "status" ] || [ "$1" = "health" ]; then
#   $NU -n -c "source '$PROVISIONING/core/nulib/lib_minimal.nu'; status-quick | table" 2>/dev/null
#   exit $?
# fi

# Environment display (fast-path)
if [ "${1:-}" = "env" ] || [ "${1:-}" = "allenv" ]; then
    $NU -n -c "source '$PROVISIONING/core/nulib/lib_minimal.nu'; env-quick | table" 2>/dev/null
    exit $?
fi

# Provider list (lightweight - reads filesystem only, no module loading)
if [ "${1:-}" = "provider" ] || [ "${1:-}" = "providers" ]; then
    if [ "${2:-}" = "list" ] || [ -z "${2:-}" ]; then
        $NU -n -c "
      source '$PROVISIONING/core/nulib/lib_minimal.nu'

      let provisioning = (\$env.PROVISIONING | default '/usr/local/provisioning')
      let providers_base = (\$provisioning | path join 'extensions' | path join 'providers')

      if not (\$providers_base | path exists) {
        print 'PROVIDERS list: (none found)'
        return
      }

      # Discover all providers from directories
      let all_providers = (
        ls \$providers_base | where type == 'dir' | each {|prov_dir|
          let prov_name = (\$prov_dir.name | path basename)
          if \$prov_name != 'prov_lib' {
            {name: \$prov_name, type: 'providers', version: '0.0.1'}
          } else {
            null
          }
        } | compact
      )

      if (\$all_providers | length) == 0 {
        print 'PROVIDERS list: (none found)'
      } else {
        print 'PROVIDERS list: '
        print ''
        \$all_providers | table
      }
    " 2>/dev/null
        exit $?
    fi
fi

# Taskserv list (fast-path) - avoid full system load
if [ "${1:-}" = "taskserv" ] || [ "${1:-}" = "task" ]; then
    if [ "${2:-}" = "list" ] || [ -z "${2:-}" ]; then
        $NU -n -c "
      # Direct implementation of taskserv discovery (no dependency loading)
      # Taskservs are nested: extensions/taskservs/{category}/{name}/kcl/
      let provisioning = (\$env.PROVISIONING | default '/usr/local/provisioning')
      let taskservs_base = (\$provisioning | path join 'extensions' | path join 'taskservs')

      if not (\$taskservs_base | path exists) {
        print '📦 Available Taskservs: (none found)'
        return null
      }

      # Discover all taskservs from nested categories
      let all_taskservs = (
        ls \$taskservs_base | where type == 'dir' | each {|cat_dir|
          let category = (\$cat_dir.name | path basename)
          let cat_path = (\$taskservs_base | path join \$category)
          if (\$cat_path | path exists) {
            ls \$cat_path | where type == 'dir' | each {|ts|
              let ts_name = (\$ts.name | path basename)
              {task: \$ts_name, mode: \$category, info: ''}
            }
          } else {
            []
          }
        } | flatten
      )

      if (\$all_taskservs | length) == 0 {
        print '📦 Available Taskservs: (none found)'
      } else {
        print '📦 Available Taskservs:'
        print ''
        \$all_taskservs | each {|ts|
          print \$\"  • (\$ts.task) [(\$ts.mode)]\"
        } | ignore
      }
    " 2>/dev/null
        exit $?
    fi
fi

# Server list (lightweight - reads filesystem only, no config loading)
if [ "${1:-}" = "server" ] || [ "${1:-}" = "s" ]; then
    if [ "${2:-}" = "list" ] || [ -z "${2:-}" ]; then
        # Extract --infra flag from remaining args
        INFRA_FILTER=""
        shift
        [ "${1:-}" = "list" ] && shift
        while [ $# -gt 0 ]; do
            case "${1:-}" in
            --infra | -i)
                INFRA_FILTER="${2:-}"
                shift 2
                ;;
            *) shift ;;
            esac
        done

        $NU -n -c "
      source '$PROVISIONING/core/nulib/lib_minimal.nu'

      # Get active workspace
      let active_ws = (workspace-active)
      if (\$active_ws | is-empty) {
        print 'No active workspace'
        return
      }

      # Get workspace path from config
      let user_config_path = if (\$env.HOME | path exists) {
        (
          \$env.HOME | path join 'Library' | path join 'Application Support' |
          path join 'provisioning' | path join 'user_config.yaml'
        )
      } else {
        ''
      }

      if not (\$user_config_path | path exists) {
        print 'Config not found'
        return
      }

      let config = (open \$user_config_path)
      let workspaces = (\$config | get --optional workspaces | default [])
      let ws = (\$workspaces | where { \$in.name == \$active_ws } | first)

      if (\$ws | is-empty) {
        print 'Workspace not found'
        return
      }

      let ws_path = \$ws.path
      let infra_path = (\$ws_path | path join 'infra')

      if not (\$infra_path | path exists) {
        print 'No infrastructures found'
        return
      }

      # Filter by infrastructure if specified
      let infra_filter = \"$INFRA_FILTER\"

      # List server definitions from infrastructure (filtered if --infra specified)
      let servers = (
        ls \$infra_path | where type == 'dir' | each {|infra|
          let infra_name = (\$infra.name | path basename)

          # Skip if filter is specified and doesn't match
          if ((\$infra_filter | is-not-empty) and (\$infra_name != \$infra_filter)) {
            []
          } else {
            let servers_file = ($infra_path | path join \$infra_name | path join 'defs' | path join 'servers.ncl')
            let servers_file_kcl = ($infra_path | path join \$infra_name | path join 'defs' | path join 'servers.k')

            if ($servers_file | path exists) {
              # Parse the Nickel servers.ncl file to extract server hostnames
              let content = (open \$servers_file --raw)
              # Extract hostnames from hostname = "..." patterns by splitting on quotes
              let hostnames = (
                \$content
                | split row \"\\n\"
                | where {|line| \$line | str contains \"hostname = \\\"\" }
                | each {|line|
                    # Split by quotes to extract hostname value
                    let parts = (\$line | split row \"\\\"\")
                    if (\$parts | length) >= 2 {
                      \$parts | get 1
                    } else {
                      \"\"
                    }
                  }
                | where {|h| (\$h | is-not-empty) }
              )

              \$hostnames | each {|srv_name|
                {
                  name: \$srv_name
                  infrastructure: \$infra_name
                  path: \$servers_file
                }
              }
            } else {
              []
            }
          }
        } | flatten
      )

      if (\$servers | length) == 0 {
        print '📦 Available Servers: (none configured)'
      } else {
        print '📦 Available Servers:'
        print ''
        \$servers | each {|srv|
          print \$\"  • (\$srv.name) [(\$srv.infrastructure)]\"
        } | ignore
      }
    " 2>/dev/null
        exit $?
    fi
fi

# Cluster list (lightweight - reads filesystem only)
if [ "${1:-}" = "cluster" ] || [ "${1:-}" = "cl" ]; then
    if [ "${2:-}" = "list" ] || [ -z "${2:-}" ]; then
        $NU -n -c "
      source '$PROVISIONING/core/nulib/lib_minimal.nu'

      # Get active workspace
      let active_ws = (workspace-active)
      if (\$active_ws | is-empty) {
        print 'No active workspace'
        return
      }

      # Get workspace path from config
      let user_config_path = (
        \$env.HOME | path join 'Library' | path join 'Application Support' |
        path join 'provisioning' | path join 'user_config.yaml'
      )

      if not (\$user_config_path | path exists) {
        print 'Config not found'
        return
      }

      let config = (open \$user_config_path)
      let workspaces = (\$config | get --optional workspaces | default [])
      let ws = (\$workspaces | where { \$in.name == \$active_ws } | first)

      if (\$ws | is-empty) {
        print 'Workspace not found'
        return
      }

      let ws_path = \$ws.path

      # List all clusters from workspace
      let clusters = (
        if ((\$ws_path | path join '.clusters') | path exists) {
          let clusters_path = (\$ws_path | path join '.clusters')
          ls \$clusters_path | where type == 'dir' | each {|cl|
            let cl_name = (\$cl.name | path basename)
            {
              name: \$cl_name
              path: \$cl.name
            }
          }
        } else {
          []
        }
      )

      if (\$clusters | length) == 0 {
        print '🗂️ Available Clusters: (none found)'
      } else {
        print '🗂️ Available Clusters:'
        print ''
        \$clusters | each {|cl|
          print \$\"  • (\$cl.name)\"
        } | ignore
      }
    " 2>/dev/null
        exit $?
    fi
fi

# Infra list (lightweight - reads filesystem only)
if [ "${1:-}" = "infra" ] || [ "${1:-}" = "inf" ]; then
    if [ "${2:-}" = "list" ] || [ -z "${2:-}" ]; then
        $NU -n -c "
      source '$PROVISIONING/core/nulib/lib_minimal.nu'

      # Get active workspace
      let active_ws = (workspace-active)
      if (\$active_ws | is-empty) {
        print 'No active workspace'
        return
      }

      # Get workspace path from config
      let user_config_path = (
        \$env.HOME | path join 'Library' | path join 'Application Support' |
        path join 'provisioning' | path join 'user_config.yaml'
      )

      if not (\$user_config_path | path exists) {
        print 'Config not found'
        return
      }

      let config = (open \$user_config_path)
      let workspaces = (\$config | get --optional workspaces | default [])
      let ws = (\$workspaces | where { \$in.name == \$active_ws } | first)

      if (\$ws | is-empty) {
        print 'Workspace not found'
        return
      }

      let ws_path = \$ws.path
      let infra_path = (\$ws_path | path join 'infra')

      if not (\$infra_path | path exists) {
        print '📁 Available Infrastructures: (none configured)'
        return
      }

      # List all infrastructures
      let infras = (
        ls \$infra_path | where type == 'dir' | each {|inf|
          let inf_name = (\$inf.name | path basename)
          let inf_full_path = (\$infra_path | path join \$inf_name)
          let has_config = ((\$inf_full_path | path join 'settings.k') | path exists)

          {
            name: \$inf_name
            configured: \$has_config
            modified: \$inf.modified
          }
        }
      )

      if (\$infras | length) == 0 {
        print '📁 Available Infrastructures: (none found)'
      } else {
        print '📁 Available Infrastructures:'
        print ''
        \$infras | each {|inf|
          let status = if \$inf.configured { '✓' } else { '○' }
          let output = \"  [\" + \$status + \"] \" + \$inf.name
          print \$output
        } | ignore
      }
    " 2>/dev/null
        exit $?
    fi
fi

# Config validation (lightweight - validates config structure without full load)
if [ "${1:-}" = "validate" ]; then
    if [ "${2:-}" = "config" ] || [ -z "${2:-}" ]; then
        $NU -n -c "
      source '$PROVISIONING/core/nulib/lib_minimal.nu'

      try {
        # Get active workspace
        let active_ws = (workspace-active)
        if (\$active_ws | is-empty) {
          print '❌ Error: No active workspace'
          return
        }

        # Get workspace path from config
        let user_config_path = (
          \$env.HOME | path join 'Library' | path join 'Application Support' |
          path join 'provisioning' | path join 'user_config.yaml'
        )

        if not (\$user_config_path | path exists) {
          print '❌ Error: User config not found at' \$user_config_path
          return
        }

        let config = (open \$user_config_path)
        let workspaces = (\$config | get --optional workspaces | default [])
        let ws = (\$workspaces | where { \$in.name == \$active_ws } | first)

        if (\$ws | is-empty) {
          print '❌ Error: Workspace' \$active_ws 'not found in config'
          return
        }

        let ws_path = \$ws.path

        # Validate workspace structure
        let required_dirs = ['infra', 'config', '.clusters']
        let infra_path = (\$ws_path | path join 'infra')
        let config_path = (\$ws_path | path join 'config')

        let missing_dirs = \$required_dirs | where { not ((\$ws_path | path join \$in) | path exists) }

        if (\$missing_dirs | length) > 0 {
          print '⚠️  Warning: Missing directories:' (\$missing_dirs | str join ', ')
        }

        # Validate infrastructures have required files
        if (\$infra_path | path exists) {
          let infras = (ls \$infra_path | where type == 'dir')
          let invalid_infras = (
            \$infras | each {|inf|
              let inf_name = (\$inf.name | path basename)
              let inf_full_path = (\$infra_path | path join \$inf_name)
              if not ((\$inf_full_path | path join 'settings.k') | path exists) {
                \$inf_name
              } else {
                null
              }
            } | compact
          )

          if (\$invalid_infras | length) > 0 {
            print '⚠️  Warning: Infrastructures missing settings.k:' (\$invalid_infras | str join ', ')
          }
        }

        # Validate user config structure
        let has_active = ((\$config | get --optional active_workspace) != null)
        let has_workspaces = ((\$config | get --optional workspaces) != null)
        let has_preferences = ((\$config | get --optional preferences) != null)

        if not \$has_active {
          print '⚠️  Warning: Missing active_workspace in user config'
        }

        if not \$has_workspaces {
          print '⚠️  Warning: Missing workspaces list in user config'
        }

        if not \$has_preferences {
          print '⚠️  Warning: Missing preferences in user config'
        }

        # Summary
        print ''
        print '✓ Configuration validation complete for workspace:' \$active_ws
        print '  Path:' \$ws_path
        print '  Status: Valid (with warnings, if any listed above)'
      } catch {|err|
        print '❌ Validation error:' \$err
      }
    " 2>/dev/null
        exit $?
    fi
fi

if [ ! -d "$PROVISIONING_USER_CONFIG" ] || [ ! -r "$PROVISIONING_CONTEXT_PATH" ]; then
    [ ! -x "$PROVISIONING/core/nulib/provisioning setup" ] && echo "$PROVISIONING/core/nulib/provisioning setup  not found" && exit 1
    cd "$PROVISIONING/core/nulib"
    ./"provisioning setup"
    echo ""
    read -p "Use [enter] to continue or [ctrl-c] to cancel"
fi
[ ! -r "$PROVISIONING_USER_CONFIG/config.nu" ] && echo "$PROVISIONING_USER_CONFIG/config.nu not found" && exit 1
[ ! -r "$PROVISIONING_USER_CONFIG/env.nu" ] && echo "$PROVISIONING_USER_CONFIG/env.nu not found" && exit 1

NU_ARGS=(--config "$PROVISIONING_USER_CONFIG/config.nu" --env-config "$PROVISIONING_USER_CONFIG/env.nu")
export PROVISIONING_ARGS="$CMD_ARGS" NU_ARGS="$NU_ARGS"
#export NU_ARGS=${NU_ARGS//Application Support/Application\\ Support}

# Suppress repetitive config export output during initialization
export PROVISIONING_QUIET_EXPORT="true"

# Export NU_LIB_DIRS so Nushell can find modules during parsing
export NU_LIB_DIRS="$PROVISIONING/core/nulib:/opt/provisioning/core/nulib:/usr/local/provisioning/core/nulib"

# ============================================================================
# DAEMON ROUTING - ENABLED (Phase 3.7: CLI Daemon Integration)
# ============================================================================
# Redesigned daemon with pre-loaded Nushell environment (no CLI callback).
# Routes eligible commands to HTTP daemon for <100ms execution.
# Gracefully falls back to full load if daemon unavailable.
#
# ARCHITECTURE:
#   1. Check daemon health (curl with 5ms timeout)
#   2. Route eligible commands to daemon via HTTP POST
#   3. Fall back to full load if daemon unavailable
#   4. Zero breaking changes (graceful degradation)
#
# PERFORMANCE:
#   - With daemon: <100ms for ALL commands
#   - Without daemon: ~430ms (normal behavior)
#   - Daemon fallback: Automatic, user sees no difference

if [ -n "$PROVISIONING_MODULE" ]; then
    if [[ -x $PROVISIONING/core/nulib/$RUNNER\ $PROVISIONING_MODULE ]]; then
        $NU "${NU_ARGS[@]}" "$PROVISIONING/core/nulib/$RUNNER $PROVISIONING_MODULE" $CMD_ARGS
    else
        echo "Error \"$PROVISIONING/core/nulib/$RUNNER $PROVISIONING_MODULE\" not found"
    fi
else
    # Only redirect stdin for non-interactive commands (nu command needs interactive stdin)
    if [ "${1:-}" = "nu" ]; then
        # For interactive mode, start nu with provisioning environment
        export PROVISIONING_CONFIG="$PROVISIONING_USER_CONFIG"
        # Start nu interactively - it will use the config and env from NU_ARGS
        $NU "${NU_ARGS[@]}"
    else
        # Don't redirect stdin for infrastructure commands - they may need interactive input
        # Only redirect for commands we know are safe
        case "${1:-}" in
        help | h | --help | --info | -i | -v | --version | env | allenv | status | health | list | ls | l | workspace | ws | provider | providers | validate | plugin | plugins | nuinfo | platform | plat)
            # Safe commands - can use /dev/null
            $NU "${NU_ARGS[@]}" "$PROVISIONING/core/nulib/$RUNNER" $CMD_ARGS </dev/null
            ;;
        *)
            # All other commands (create, delete, server, taskserv, etc.) - keep stdin open
            # NOTE: PROVISIONING_MODULE is automatically inherited by Nushell from bash environment
            $NU "${NU_ARGS[@]}" "$PROVISIONING/core/nulib/$RUNNER" $CMD_ARGS
            ;;
        esac
    fi
fi
