#!/usr/bin/env bash
# Info: Script to run Provisioning
# Author: JesusPerezLorenzo
# Release: 1.0.11
# Date: 2026-01-14

set +o errexit
set +o pipefail

# Debug: log startup
[ "$PROVISIONING_DEBUG_STARTUP" = "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"

[ "$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
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" = "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"

      ;;
  darwin) PROVISIONING_USER_CONFIG="$HOME/Library/Application Support/provisioning/nushell"
      PROVISIONING_CONTEXT_PATH="$HOME/Library/Application Support/provisioning/$DEFAULT_CONTEXT_TEMPLATE"
      ;;
  *) PROVISIONING_USER_CONFIG="$HOME/.config/provisioning/nushell"
      PROVISIONING_CONTEXT_PATH="$HOME/.config/provisioning/$DEFAULT_CONTEXT_TEMPLATE"
      ;;
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
if [ "$1" = "server" ] || [ "$1" = "s" ]; then
    if [ "$2" = "list" ] || [ -z "$2" ]; then
        # Light command - try daemon
        [ "$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
        [ "$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 (uses help_minimal.nu)
if [ -z "$1" ] || [ "$1" = "help" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ] || [ "$1" = "--helpinfo" ]; then
  category="${2:-}"
  # 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 '$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 | 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)
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.k')

            if (\$servers_file | path exists) {
              # Parse the KCL servers.k file to extract server names
              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}

# 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)
                # 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
