# VM Domain Command Handlers
# Handles: vm, vm hosts, vm lifecycle commands

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

# Helper to run module commands
def run_module [
  args: string
  module: string
  option?: string
  --exec
] {
  let use_debug = if ($env.PROVISIONING_DEBUG? | default false) { "-x" } else { "" }

  # Always add --notitles when dispatching to submodules to prevent double title display
  if $exec {
    exec $"($env.PROVISIONING_NAME)" $use_debug -mod $module ($option | default "") $args --notitles
  } else {
    ^$"($env.PROVISIONING_NAME)" $use_debug -mod $module ($option | default "") $args --notitles
  }
}

# Main VM command dispatcher
export def handle_vm_command [
  command: string
  ops: string
  flags: record
] {
  set_debug_env $flags

  match $command {
    "vm" => { handle_vm_core $ops $flags }
    "hosts" => { handle_vm_hosts $ops $flags }
    "lifecycle" => { handle_vm_lifecycle $ops $flags }
    "info" => { handle_vm_info $ops $flags }
    _ => {
      # Direct commands (create, list, start, stop, delete, ssh, exec, scp)
      if $command in ["create" "list" "start" "stop" "delete" "ssh" "exec" "scp"] {
        handle_vm_core $"($command) ($ops)" $flags
      } else {
        print $"❌ Unknown VM command: ($command)"
        print ""
        print "Available VM commands:"
        print "  vm         - Core VM operations (create, list, start, stop, delete, info, ssh, exec, scp)"
        print "  vm hosts   - Host management (check, prepare, list, status, ensure)"
        print "  vm lifecycle - VM persistence (permanent/temporary, cleanup, scheduler)"
        print ""
        print "Shortcuts:"
        print "  vmi        - Quick VM info"
        print "  vmh        - VM hosts management"
        print "  vml        - VM lifecycle management"
        print ""
        print "Use 'provisioning vm help' or 'provisioning help vm' for more details"
        exit 1
      }
    }
  }
}

# Core VM command handler
def handle_vm_core [ops: string, flags: record] {
  # Show help if no subcommand provided
  if ($ops | is-empty) {
    print ""
    print $"(ansi cyan_bold)VM Core Operations(ansi reset)"
    print "=================="
    print ""
    print "Usage: provisioning vm <command> [options]"
    print "   or: provisioning infra vm <command> [options]"
    print ""
    print "Commands:"
    print "  create [config]    Create new VM"
    print "  list [--running]   List all VMs"
    print "  start <name>       Start VM"
    print "  stop <name>        Stop VM"
    print "  delete <name>      Delete VM"
    print "  info <name>        VM information"
    print "  ssh <name>         SSH into VM"
    print "  exec <name> <cmd>  Execute command in VM"
    print "  scp <src> <dst>    Copy files to/from VM"
    print ""
    print "Examples:"
    print "  provisioning vm create web-01.yaml"
    print "  provisioning vm list --running"
    print "  provisioning vmi web-01    # Quick info"
    print "  provisioning vm ssh web-01"
    print ""
    print $"(ansi yellow_bold)Authentication:(ansi reset)"
    print "  delete, stop require auth (bypass with --check)"
    print ""
    return
  }

  # Parse operation
  let operation_parts = ($ops | split row " ")
  let action = if ($operation_parts | is-empty) { "" } else { $operation_parts | first }

  # Determine operation type
  let operation_type = match $action {
    "create" | "c" => "create"
    "delete" | "d" | "remove" => "delete"
    "stop" => "stop"
    "start" => "start"
    _ => "read"
  }

  # Check authentication if not in check mode and not a read operation
  if not (is-check-mode $flags) and $operation_type != "read" {
    let operation_name = $"vm ($action)"

    if $operation_type in ["delete" "stop"] {
      check-auth-for-destructive $operation_name --allow-skip
    } else if $operation_type in ["create" "start"] {
      if (config-get "environment" "dev") == "prod" {
        check-auth-for-production $operation_name --allow-skip
      } else {
        let allow_skip = (config-get "security.bypass.allow_skip_auth" false)
        if $allow_skip {
          require-auth $operation_name --allow-skip
        } else {
          require-auth $operation_name
        }
      }
    }
  }

  # Execute VM command
  let module_args = build_module_args $flags $ops
  run_module $module_args "vm" --exec
}

# VM hosts command handler
def handle_vm_hosts [ops: string, flags: record] {
  # Show help if no subcommand provided
  if ($ops | is-empty) {
    print ""
    print $"(ansi cyan_bold)VM Hosts Management(ansi reset)"
    print "==================="
    print ""
    print "Usage: provisioning vm hosts <command> [options]"
    print "   or: provisioning vmh <command> [options]"
    print ""
    print "Commands:"
    print "  check        Check hypervisor capability"
    print "  prepare      Prepare host for VMs"
    print "  list         List available hosts"
    print "  status       Host status"
    print "  ensure       Ensure VM support"
    print ""
    print "Examples:"
    print "  provisioning vmh check"
    print "  provisioning vmh prepare --check"
    print "  provisioning vm hosts status"
    print ""
    print $"(ansi yellow_bold)Authentication:(ansi reset)"
    print "  prepare, ensure may require auth in production"
    print ""
    return
  }

  # Parse operation
  let operation_parts = ($ops | split row " ")
  let action = if ($operation_parts | is-empty) { "" } else { $operation_parts | first }

  # Determine operation type
  let operation_type = match $action {
    "prepare" | "ensure" => "modify"
    _ => "read"
  }

  # Check authentication for modifying operations in production
  if not (is-check-mode $flags) and $operation_type == "modify" {
    let operation_name = $"vm hosts ($action)"

    if (config-get "environment" "dev") == "prod" {
      check-auth-for-production $operation_name --allow-skip
    } else {
      let allow_skip = (config-get "security.bypass.allow_skip_auth" false)
      if $allow_skip {
        require-auth $operation_name --allow-skip
      } else {
        require-auth $operation_name
      }
    }
  }

  # Execute VM hosts command
  let module_args = build_module_args $flags $ops
  run_module $module_args "vm_hosts" --exec
}

# VM lifecycle command handler
def handle_vm_lifecycle [ops: string, flags: record] {
  # Show help if no subcommand provided
  if ($ops | is-empty) {
    print ""
    print $"(ansi cyan_bold)VM Lifecycle Management(ansi reset)"
    print "======================="
    print ""
    print "Usage: provisioning vm lifecycle <command> [options]"
    print "   or: provisioning vml <command> [options]"
    print ""
    print "Commands:"
    print "  list-permanent       List permanent VMs"
    print "  list-temporary       List temporary VMs"
    print "  make-permanent       Mark VM as permanent"
    print "  make-temporary       Mark VM as temporary"
    print "  cleanup-now          Cleanup expired VMs"
    print "  extend-ttl           Extend VM TTL"
    print "  scheduler start      Start cleanup scheduler"
    print "  scheduler stop       Stop cleanup scheduler"
    print "  scheduler status     Scheduler status"
    print ""
    print "Examples:"
    print "  provisioning vml list-temporary"
    print "  provisioning vml make-permanent web-01"
    print "  provisioning vml cleanup-now --check"
    print "  provisioning vm lifecycle scheduler start"
    print ""
    print $"(ansi yellow_bold)Authentication:(ansi reset)"
    print "  cleanup-now, scheduler require auth for destructive operations"
    print ""
    return
  }

  # Parse operation
  let operation_parts = ($ops | split row " ")
  let action = if ($operation_parts | is-empty) { "" } else { $operation_parts | first }

  # Determine operation type
  let operation_type = match $action {
    "cleanup-now" => "delete"
    "scheduler" => "modify"
    "make-permanent" | "make-temporary" | "extend-ttl" => "modify"
    _ => "read"
  }

  # Check authentication for destructive and modifying operations
  if not (is-check-mode $flags) and $operation_type != "read" {
    let operation_name = $"vm lifecycle ($action)"

    if $operation_type == "delete" {
      check-auth-for-destructive $operation_name --allow-skip
    } else if $operation_type == "modify" {
      if (config-get "environment" "dev") == "prod" {
        check-auth-for-production $operation_name --allow-skip
      } else {
        let allow_skip = (config-get "security.bypass.allow_skip_auth" false)
        if $allow_skip {
          require-auth $operation_name --allow-skip
        } else {
          require-auth $operation_name
        }
      }
    }
  }

  # Execute VM lifecycle command
  let module_args = build_module_args $flags $ops
  run_module $module_args "vm_lifecycle" --exec
}

# VM info shortcut handler
def handle_vm_info [ops: string, flags: record] {
  # Prepend "info" to ops if not empty, otherwise just "info"
  let info_ops = if ($ops | is-empty) { "info" } else { $"info ($ops)" }
  let module_args = build_module_args $flags $info_ops
  run_module $module_args "vm" --exec
}
