# Orchestration Command Handlers
# Handles: job (orchestrator jobs), workflow (WorkflowDef), batch, orchestrator commands

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

# 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 { "" }

  if $exec {
    exec $"($env.PROVISIONING_NAME)" $use_debug -mod $module ($option | default "") $args
  } else {
    ^$"($env.PROVISIONING_NAME)" $use_debug -mod $module ($option | default "") $args
  }
}

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

  match $command {
    "job"      => { handle_job $ops $flags }
    "workflow" => { handle_workflowdef $ops $flags }
    "batch"    => { handle_batch $ops $flags }
    "orchestrator" => { handle_orchestrator $ops $flags }
    _ => {
      print $"❌ Unknown orchestration command: ($command)"
      print ""
      print "Available orchestration commands:"
      print "  job           - Orchestrator job management (list, status, monitor, submit)"
      print "  workflow      - Workspace WorkflowDef management (list, show, run, validate, status)"
      print "  batch         - Batch operations (submit, monitor, rollback, stats)"
      print "  orchestrator  - Orchestrator lifecycle (start, stop, status, health)"
      print ""
      print "Use 'provisioning help orchestration' for more details"
      exit 1
    }
  }
}

# Job command handler — orchestrator HTTP API jobs
def handle_job [ops: string, flags: record] {
  # Authentication check for workflow operations (metadata-driven)
  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 {
    "rollback" | "cancel" => "delete"
    "submit" | "create" => "create"
    "update" | "modify" => "modify"
    _ => "read"
  }

  # Check authentication using metadata-driven approach
  if not (is-check-mode $flags) and $operation_type != "read" {
    let operation_name = $"workflow ($action)"
    check-operation-auth $operation_name $operation_type $flags
  }

  # Call workflow management commands directly (avoid -mod routing conflict)
  use ../../workflows/management.nu *

  let orchestrator = ($flags.orchestrator? | default "")
  let status_filter = ($flags.status? | default "")
  let days = ($flags.days? | default 7 | into int)
  let dry_run = ($flags.dry_run? | default false)

  # DEBUG
  if $action == "browse" {
    print $"DEBUG: Handling browse action, ops=($ops)"
  }

  match $action {
    "list" => {
      let limit_arg = if ($operation_parts | length) > 1 {
        let limit_str = ($operation_parts | get 1 | str trim)
        let result = (do { $limit_str | into int } | complete)
        if $result.exit_code == 0 { ($result.stdout | str trim | into int) } else { null }
      } else {
        null
      }

      if ($limit_arg | is-not-empty) {
        workflow list $limit_arg --orchestrator $orchestrator --status $status_filter
      } else {
        workflow list --orchestrator $orchestrator --status $status_filter
      }
    }
    "status" => {
      if ($operation_parts | length) < 2 {
        print "❌ Error: job status requires a task ID"
        return
      }
      let task_id = ($operation_parts | get 1)
      workflow status $task_id --orchestrator $orchestrator
    }
    "monitor" => {
      if ($operation_parts | length) < 2 {
        print "❌ Error: job monitor requires a task ID"
        return
      }
      let task_id = ($operation_parts | get 1)
      workflow monitor $task_id --orchestrator $orchestrator
    }
    "stats" => { workflow stats --orchestrator $orchestrator }
    "cleanup" => {
      if $dry_run {
        workflow cleanup --orchestrator $orchestrator --days $days --dry-run
      } else {
        workflow cleanup --orchestrator $orchestrator --days $days
      }
    }
    "orchestrator" => { workflow orchestrator --orchestrator $orchestrator }
    "browse" => {
      let limit_arg = if ($operation_parts | length) > 1 {
        let limit_str = ($operation_parts | get 1 | str trim)
        let result = (do { $limit_str | into int } | complete)
        if $result.exit_code == 0 { ($result.stdout | str trim | into int) } else { null }
      } else {
        null
      }

      if ($limit_arg | is-not-empty) {
        workflow browse $limit_arg --orchestrator $orchestrator
      } else {
        workflow browse --orchestrator $orchestrator
      }
    }
    "submit" => {
      if ($operation_parts | length) < 4 {
        print "❌ Error: job submit requires: job_type operation target [infra] [settings]"
        return
      }
      let workflow_type = ($operation_parts | get 1)
      let operation_name = ($operation_parts | get 2)
      let target = ($operation_parts | get 3)
      let infra = if ($operation_parts | length) > 4 { $operation_parts | get 4 } else { "" }
      let settings = if ($operation_parts | length) > 5 { $operation_parts | get 5 } else { "" }
      let check_mode = (is-check-mode $flags)
      let wait = ($flags.wait? | default false)

      workflow submit $workflow_type $operation_name $target $infra $settings --check=$check_mode --wait=$wait --orchestrator $orchestrator
    }
    "" => {
      print "❌ Error: job subcommand required — use: list, status, monitor, stats, cleanup, browse, submit"
      return
    }
    _ => {
      print $"❌ Error: unknown job subcommand '$action'"
      return
    }
  }
}

# WorkflowDef command handler — workspace workflow declarations (workflows/*.ncl)
def handle_workflowdef [ops: string, flags: record] {
  let parts     = ($ops | split row " ")
  let action    = if ($parts | is-empty) { "" } else { $parts | first }
  let workspace = ($flags.workspace? | default ($flags.ws? | default ""))
  let infra     = ($flags.infra? | default "")
  let dry_run   = ($flags.dry_run? | default false)

  use ../../main_provisioning/workflow.nu *

  match $action {
    "list" => {
      if ($workspace | is-not-empty) {
        main workflow list --workspace $workspace
      } else {
        main workflow list
      }
    }
    "show" => {
      if ($parts | length) < 2 {
        print "❌ Error: workflow show requires a workflow id"
        return
      }
      let wf_id = ($parts | get 1)
      if ($workspace | is-not-empty) {
        use ../../main_provisioning/ontoref-queries.nu *
        main describe workflow $wf_id --workspace $workspace
      } else {
        use ../../main_provisioning/ontoref-queries.nu *
        main describe workflow $wf_id
      }
    }
    "run" => {
      if ($parts | length) < 2 {
        print "❌ Error: workflow run requires a workflow id"
        return
      }
      let wf_id = ($parts | get 1)
      if ($workspace | is-not-empty) and $dry_run {
        main workflow run $wf_id --workspace $workspace --dry-run
      } else if ($workspace | is-not-empty) {
        main workflow run $wf_id --workspace $workspace
      } else if $dry_run {
        main workflow run $wf_id --dry-run
      } else {
        main workflow run $wf_id
      }
    }
    "validate" => {
      if ($workspace | is-not-empty) {
        main workflow validate --workspace $workspace
      } else {
        main workflow validate
      }
    }
    "status" => {
      if ($parts | length) < 2 {
        print "❌ Error: workflow status requires a workflow id"
        return
      }
      let wf_id = ($parts | get 1)
      if ($workspace | is-not-empty) {
        main workflow status $wf_id --workspace $workspace
      } else {
        main workflow status $wf_id
      }
    }
    "" => {
      print "❌ Error: workflow subcommand required"
      print ""
      print "  list [--workspace <ws>]       List workspace WorkflowDef declarations"
      print "  show <id> [--workspace <ws>]  Show workflow definition + FSM state"
      print "  run  <id> [--workspace <ws>]  Execute a WorkflowDef"
      print "  validate [--workspace <ws>]   Cross-validate workflows against components"
      print "  status <id> [--workspace <ws>] Show FSM dimension state"
    }
    _ => {
      print $"❌ Unknown workflow subcommand: ($action)"
    }
  }
}

# Batch command handler
def handle_batch [ops: string, flags: record] {
  # Authentication check for batch operations (metadata-driven)
  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 {
    "submit" | "create" => "create"
    "rollback" | "cancel" => "delete"
    "update" | "modify" => "modify"
    _ => "read"
  }

  # Check authentication using metadata-driven approach
  if not (is-check-mode $flags) and $operation_type != "read" {
    let operation_name = $"batch ($action)"
    check-operation-auth $operation_name $operation_type $flags
  }

  let args = build_module_args $flags $ops
  run_module $args "batch" --exec
}

# Orchestrator command handler
def handle_orchestrator [ops: string, flags: record] {
  # Authentication check for orchestrator operations (metadata-driven)
  let operation_parts = ($ops | split row " ")
  let action = if ($operation_parts | is-empty) { "" } else { $operation_parts | first }

  # Determine operation type (orchestrator start/stop are modify operations)
  let operation_type = match $action {
    "start" => "modify"
    "stop" => "modify"
    _ => "read"
  }

  # Check authentication using metadata-driven approach
  if not (is-check-mode $flags) and $operation_type != "read" {
    let operation_name = $"orchestrator ($action)"
    check-operation-auth $operation_name $operation_type $flags
  }

  # Orchestrator has simpler argument requirements
  run_module $ops "orchestrator" --exec
}
