#compdef pkf
# pkf zsh completion.
# Suggested install:  pkf completion zsh > "${fpath[1]}/_pkf"
# then `compinit` (re-source ~/.zshrc).

_pkf() {
  local -a subcommands
  subcommands=(
    'init:write a starter Taskfile.pkl'
    'list:list declared tasks'
    'describe:show a single task'\''s desc / params / inputs / outputs / cache / deps'
    'info:structured snapshot (schema version + defaults + tasks + workflowTests)'
    'run:run one or more tasks'
    'up:supervise long-running services'
    'doctor:diagnose pkfire setup'
    'lint:detect Taskfile issues'
    'format:pkl format -w wrapper'
    'hooks:manage .git/hooks shims'
    'affected:run tasks whose inputs changed since <ref>'
    'clean:remove declared outputs'
    'cache:inspect / clean the local CAS'
    'completion:emit shell completion script'
    'graph:emit DAG (dot / mermaid / tree / json)'
    'explain:dump or compare inputs to the action key'
    'migrate:rewrite Taskfile schema version'
    'pkl-cache:warm the local Pkl package cache'
    'version:print pkf version'
    'help:show usage'
  )

  if (( CURRENT == 2 )); then
    _describe 'subcommand' subcommands
    return
  fi

  case "${words[2]}" in
    list)
      if [[ "${words[$((CURRENT-1))]}" == "--color" ]]; then
        _values 'color' auto always never
      elif [[ "${words[$CURRENT]}" == -* ]]; then
        _values 'list option' \
          '-f[path to Taskfile.pkl]' \
          '--file[path to Taskfile.pkl]' \
          '-v[show cmd preview and deps]' \
          '--verbose[show cmd preview and deps]' \
          '--long[show compact audit table]' \
          '--json[emit machine-readable output]' \
          '--all[include internal tasks]' \
          '--unsorted[use declaration order]' \
          '--source-order[use declaration order]' \
          '--color[when to color output]'
      fi
      ;;
    lint)
      if [[ "${words[$CURRENT]}" == -* ]]; then
        _values 'lint option' \
          '-f[path to Taskfile.pkl]' \
          '--file[path to Taskfile.pkl]' \
          '--json[emit machine-readable output]' \
          '--fix[apply safe fixes]' \
          '--dry-run[show fixes without writing files]'
      fi
      ;;
    doctor)
      if [[ "${words[$CURRENT]}" == -* ]]; then
        _values 'doctor option' \
          '-f[path to Taskfile.pkl]' \
          '--file[path to Taskfile.pkl]' \
          '--json[emit machine-readable output]' \
          '--fix[apply safe fixes]' \
          '--dry-run[show fixes without writing files]'
      fi
      ;;
    affected)
      if [[ "${words[$CURRENT]}" == -* ]]; then
        _values 'affected option' \
          '-f[path to Taskfile.pkl]' \
          '--file[path to Taskfile.pkl]' \
          '--since[git ref to diff against]' \
          '--files[simulate changed file paths]' \
          '--explain[show matching input patterns]' \
          '--check[run workflowTests]' \
          '--dry-run[preview plan without running]' \
          '--no-cache[disable cache for this run]' \
          '--refresh[skip lookup but store outputs]' \
          '--timing[print task durations]' \
          '--quiet[suppress per-task log lines]' \
          '--keep-going[do not stop on first failure]' \
          '--profile[profile name for cache keys]' \
          '--watch[recompute affected set on change]' \
          '-j[max concurrent tasks]' \
          '--jobs[max concurrent tasks]'
      else
        local -a tasks
        tasks=(${(f)"$(pkf list 2>/dev/null | awk '{print $1}')"})
        _describe 'task' tasks
      fi
      ;;
    run)
      if [[ "${words[$CURRENT]}" == -* ]]; then
        _values 'run option' \
          '-f[path to Taskfile.pkl]' \
          '--file[path to Taskfile.pkl]' \
          '--watch[re-run on input changes]' \
          '--dry-run[preview plan without running]' \
          '--print-hash[print action keys and exit]' \
          '--explain-cache[explain cache decisions and exit]' \
          '--no-cache[disable cache for this run]' \
          '--refresh[skip lookup but store outputs]' \
          '--timing[print task durations]' \
          '--quiet[suppress per-task log lines]' \
          '--keep-going[do not stop on first failure]' \
          '--profile[profile name for cache keys]' \
          '--on-fail[action on task failure]' \
          '--remote-only[consult only remote cache]' \
          '-j[max concurrent tasks]' \
          '--jobs[max concurrent tasks]'
      else
        local -a tasks
        tasks=(${(f)"$(pkf list 2>/dev/null | awk '{print $1}')"})
        _describe 'task' tasks
      fi
      ;;
    clean|up)
      local -a tasks
      tasks=(${(f)"$(pkf list 2>/dev/null | awk '{print $1}')"})
      _describe 'task' tasks
      ;;
    describe)
      if [[ "${words[$CURRENT]}" == -* ]]; then
        _values 'describe option' \
          '-f[path to Taskfile.pkl]' \
          '--file[path to Taskfile.pkl]' \
          '--json[emit machine-readable output]'
      else
        local -a tasks
        tasks=(${(f)"$(pkf list --all 2>/dev/null | awk '{print $1}')"})
        _describe 'task' tasks
      fi
      ;;
    info)
      if [[ "${words[$CURRENT]}" == -* ]]; then
        _values 'info option' \
          '-f[path to Taskfile.pkl]' \
          '--file[path to Taskfile.pkl]' \
          '--json[emit machine-readable output]' \
          '--all[include internal tasks]'
      fi
      ;;
    hooks)
      if (( CURRENT == 3 )); then
        _values 'hooks subcommand' install uninstall list
      fi
      ;;
    cache)
      if (( CURRENT == 3 )); then
        _values 'cache subcommand' stats prune rm clear
      fi
      ;;
    completion)
      if (( CURRENT == 3 )); then
        _values 'shell' bash zsh fish
      fi
      ;;
    graph)
      if [[ "${words[$((CURRENT-1))]}" == "--format" ]]; then
        _values 'format' dot mermaid tree json
      elif [[ "${words[$CURRENT]}" == -* ]]; then
        _values 'graph option' \
          '-f[path to Taskfile.pkl]' \
          '--file[path to Taskfile.pkl]' \
          '--format[output format]' \
          '--json[emit machine-readable output]' \
          '--target[render only one task subgraph]' \
          '--all[include internal tasks]' \
          '--unsorted[use declaration order]' \
          '--source-order[use declaration order]' \
          '--depth[limit dependency traversal]'
      fi
      ;;
    explain)
      if [[ "${words[$CURRENT]}" == -* ]]; then
        _values 'explain option' \
          '-f[path to Taskfile.pkl]' \
          '--file[path to Taskfile.pkl]' \
          '--diff[compare against another Taskfile.pkl]'
      else
        local -a tasks
        tasks=(${(f)"$(pkf list 2>/dev/null | awk '{print $1}')"})
        _describe 'task' tasks
      fi
      ;;
    migrate)
      if [[ "${words[$CURRENT]}" == -* ]]; then
        _values 'migrate option' \
          '-f[path to Taskfile.pkl]' \
          '--file[path to Taskfile.pkl]' \
          '--to[target schema version]' \
          '--dry-run[preview rewrite without writing]' \
          '--skip-verify[skip post-migration pkl eval]'
      fi
      ;;
    pkl-cache)
      if (( CURRENT == 3 )); then
        _values 'pkl-cache subcommand' warm
      elif [[ "${words[$CURRENT]}" == -* ]]; then
        _values 'pkl-cache option' \
          '-f[path to Taskfile.pkl]' \
          '--file[path to Taskfile.pkl]'
      fi
      ;;
  esac
}

_pkf "$@"
