#compdef antidote

function _antidote_subcommands {
  local usage=$(
    antidote --help |
    command awk '
      BEGIN{OFS=":"; p=0}
      /^commands:$/ {p=1; next}
      !p{next}
      { for(i=3; i<=NF; i++) { $2=$2" "$i } }
      { print $1,$2 }
    '
  )
  local -a subcommands=("${(@f)usage}")
  _describe -t subcommands 'subcommand' subcommands "$@"
}

function _antidote_installed_bundles {
  local -a bundles=("${(@f)$(antidote list --url | awk -F'/' '{print $(NF-1)"/"$NF}')}")
  _describe 'installed bundles' bundles
}

function _antidote_bundle_kinds {
  local -a kinds=(
    'autoload' 'clone' 'defer' 'fpath' 'path' 'zsh'
  )
  _describe 'bundle kinds' kinds
}

function _antidote {
  typeset -A opt_args
  local context state line
  local curcontext="$curcontext"
  local ret=1

  _arguments -C \
    '(- *)'{-v,--version}'[Show version]' \
    '(- *)'{-h,--help}'[Show usage information]' \
    '(- *)--diagnostics[Show antidote and system diagnostics]' \
    '1: :_antidote_subcommands' \
    '*:: :->subcmds' && return 0

  case "$state" in
    (subcmds)
      case $words[1] in
        (bundle)
          _arguments \
            '(- *)'{-h,--help}'[Show usage information]' \
            && ret=0
          ;;
        (help)
          _arguments \
            '(- *)'{-h,--help}'[Show usage information]' \
            && ret=0
          ;;
        (home)
          _arguments \
            '(- *)'{-h,--help}'[Show usage information]' \
            && ret=0
          ;;
        (init)
          _arguments \
            '(- *)'{-h,--help}'[Show usage information]' \
            && ret=0
          ;;
        (install)
          _arguments \
            '(- *)'{-h,--help}'[Show usage information]' \
            '(-k --kind)'{-k,--kind}'[The kind of bundle]:kinds:_antidote_bundle_kinds' \
            '(-p --path)'{-p,--path}'[A relative subpath within the bundle where the plugin is located]' \
            '(-a --autoload)'{-a,--autoload}'[A relative subpath within the bundle where autoload function files are located]' \
            '(-c --conditional)'{-c,--conditional}'[A conditional function used to check whether to load the bundle]' \
            '(-b --branch)'{-b,--branch}'[The git branch to use]' \
            '(--pin)--pin[Pin the bundle to a specific commit SHA]' \
            '(--pre)--pre[A function to be called prior to loading the bundle]' \
            '(--post)--post[A function to be called after loading the bundle]' \
            && ret=0
          ;;
        (list)
          _arguments \
            '(- *)'{-h,--help}'[Show usage information]' \
            '(-l --long)'{-l,--long}'[Show detailed information for each bundle]' \
            '(-d --dirs)'{-d,--dirs}'[Show bundle directory paths]' \
            '(-u --url)'{-u,--url}'[Show bundle URLs only]' \
            '(-j --jsonl)'{-j,--jsonl}'[Output the bundle list in JSONL format]' \
            && ret=0
          ;;
        (load)
          _arguments \
            '(- *)'{-h,--help}'[Show usage information]' \
            && ret=0
          ;;
        (path)
          _arguments \
            '(- *)'{-h,--help}'[Show usage information]' \
            && ret=0
          ;;
        (purge)
          _arguments \
            '(- *)'{-h,--help}'[Show usage information]' \
            '(-a --all)'{-a,--all}'[Purge all cloned bundles]' \
            "*::antidote bundles:_antidote_installed_bundles" \
            && ret=0
          ;;
        (snapshot)
          if (( CURRENT == 2 )); then
            local -a snapshot_cmds=(
              'home:Show the snapshot directory'
              'list:List available snapshots'
              'remove:Remove snapshots'
              'restore:Restore bundles from a snapshot'
              'save:Save a snapshot of all cloned bundles'
            )
            _describe 'snapshot command' snapshot_cmds && ret=0
          elif (( CURRENT == 3 )) && [[ "$words[2]" == (restore|remove) ]]; then
            local -a snaps=("${(@f)$(antidote snapshot list 2>/dev/null)}")
            if (( $#snaps )); then
              compadd -V unsorted -a snaps && ret=0
            fi
          fi
          ;;
        (update)
          _arguments \
            '(- *)'{-h,--help}'[Show usage information]' \
            '(-s --self)'{-s,--self}'[Update antidote]' \
            '(-b --bundles)'{-b,--bundles}'[Update bundles]' \
            '(-n --dry-run)'{-n,--dry-run}'[Check for updates without making changes]' \
            && ret=0
          ;;
        (*)
          _arguments \
            '(- *)'{-h,--help}'[Show usage information]' \
            '*: :_files' \
            && ret=0
          ;;
      esac
      ;;
  esac

  return ret
}
_antidote "$@"

# vim: ft=zsh sw=2 ts=2 et
