#compdef ryadm

# This completion tries to fallback to git's completion for git commands.

zstyle -T ':completion:*:ryadm:argument-1:descriptions:' format && \
    zstyle ':completion:*:ryadm:argument-1:descriptions' format '%d:'
zstyle -T ':completion:*:ryadm:*:ryadm' group-name && \
    zstyle ':completion:*:ryadm:*:ryadm' group-name ''

function _ryadm-add(){
  local -a yadm_options yadm_path
  yadm_path="$(ryadm rev-parse --show-toplevel)"
  yadm_options=($(ryadm status --porcelain=v1 |
    awk -v yadm_path=${yadm_path} '{printf "%s/%s:%s\n",  yadm_path, $2, $1}' ))

  _describe 'command' yadm_options
  _files
}

function _ryadm-checkout(){
    _ryadm-add
}

_ryadm-alt() {
    return 0
}

_ryadm-bootstrap() {
    return 0
}

_ryadm-clone() {
    _arguments \
        '(--bootstrap --no-bootstrap)--bootstrap[force bootstrap, without prompt]' \
        '(--bootstrap --no-bootstrap)--no-bootstrap[prevent bootstrap, without prompt]' \
        '-f[force overwrite of existing repository]' \
        '-w[yadm work tree path]: :_files -/'

    local curcontext="${curcontext%:*:*}:git:"

    words=("git" "${words[@]}") CURRENT=$((CURRENT + 1)) service=git _git
}

_ryadm-config() {
    # TODO: complete config names
}

_ryadm-decrypt() {
    _arguments \
        '-l[list files]'
}

_ryadm-encrypt() {
    return 0
}

_ryadm-enter() {
    _arguments \
        ':command: _command_names -e' \
        '*::arguments: _normal'
}

_ryadm-git-crypt() {
    # TODO: complete git-crypt options
}

_ryadm-help() {
    return 0
}

_ryadm-init() {
    _arguments \
        '-f[force overwrite of existing repository]' \
        '-w[work tree path]: :_files -/'
}

_ryadm-list() {
    _arguments \
        '-a[list all tracked files]'
}

_ryadm-perms() {
    return 0
}

_ryadm-transcrypt() {
    integer _ret=1
    _call_function _ret _transcrypt
    return _ret
}

_ryadm-upgrade() {
    _arguments \
        '-f[force deinit of submodules]' \
        ': '
}

_ryadm-version() {
    return 0
}

_ryadm_commands() {
    local -a commands=(
        alt:'create links for alternates'
        bootstrap:'execute bootstrap'
        clone:'clone an existing yadm repository'
        config:'configure an yadm setting'
        decrypt:'decrypt files'
        encrypt:'encrypt files'
        enter:'run sub-shell with GIT variables set'
        git-crypt:'run git-crypt commands for the yadm repository'
        gitconfig:'run the git config command'
        help:'display yadm help information'
        init:'initialize an empty yadm repository'
        list:'list files tracked by yadm'
        perms:'fix perms for private files'
        transcrypt:'run transcrypt commands for the yadm repository'
        upgrade:'upgrade legacy yadm paths'
        version:'show yadm version'
    )

    local oldcontext="$curcontext"
    local curcontext="${curcontext%:*:*}:git:"

    words=("git" "${words[-1]}") CURRENT=2 service=git _git

    curcontext="$oldcontext"
    _describe -t ryadm "ryadm commands" commands

    return 0
}

_ryadm() {
    local curcontext=$curcontext state state_descr line
    declare -A opt_args

    _arguments -C \
      '(-Y --yadm-dir)'{-Y,--yadm-dir}'[override the standard yadm directory]: :_files -/' \
      '--yadm-data[override the standard yadm data directory]: :_files -/' \
      '--yadm-repo[override the standard repo path]: :_files -/' \
      '--yadm-config[override the standard config path]: :_files -/' \
      '--yadm-encrypt[override the standard encrypt path]: :_files -/' \
      '--yadm-archive[override the standard archive path]: :_files -/' \
      '--yadm-bootstrap[override the standard bootstrap path]: :_files' \
      '--help[display yadm help information]' \
      '--version[show yadm version]' \
      '(-): :->command' \
      '(-)*:: :->option-or-argument' && return

    local -a repo_args
    (( $+opt_args[--yadm-repo] )) && repo_args+=(--yadm-repo "$opt_args[--yadm-repo]")
    (( $+opt_args[--yadm-data] )) && repo_args+=(--yadm-data "$opt_args[--yadm-data]")
    local -x GIT_DIR="$(_call_program gitdir ryadm "${repo_args[@]}" introspect repo)"
    [[ -z "$GIT_DIR" ]] && return 1

    integer _ret=1
    case $state in
        (command)
            _ryadm_commands && _ret=0
            ;;
        (option-or-argument)
            curcontext=${curcontext%:*:*}:ryadm-${words[1]}:
            if ! _call_function _ret _ryadm-${words[1]}; then

                # Translate gitconfig to use the regular completion for config
                [[ ${words[1]} = "gitconfig" ]] && words[1]=config

                words=("git" "${(@)words}")
                CURRENT=$(( CURRENT + 1 ))

                curcontext=${curcontext%:*:*}:git:
                service=git _git && _ret=0
            fi
            ;;
    esac

    return _ret
}

(( $+functions[_git] )) && _ryadm
