_inary()
{
  local cur command commands options packages files

  COMPREPLY=()
  cur=${COMP_WORDS[COMP_CWORD]}

  commands="add-repo build check clean configure-pending delete-cache delta \
            emerge graph help history index info install list-available \
            list-components list-installed list-newest list-pending list-repo \
            list-sources list-upgrades rebuild-db remove remove-repo search \
            search-file update-repo upgrade"

  options="--destdir --yes-all --username --password --bandwidth-limit --verbose \
           --debug --no-color"
  packages=""
  files=""

  if [[ $COMP_CWORD -eq 1 ]] ; then
    if [[ "$cur" == -* ]]; then
      COMPREPLY=($(compgen -W "--version --help" -- $cur))
    else
      COMPREPLY=($(compgen -W "$commands --version --help" -- $cur))
    fi
    return 0;
  else
    command=${COMP_WORDS[1]}

    if [[ "$cur" == -* ]]; then
      case $command in
        @(add-repo|ar))
          options="${options} --at --ignore-check"
          ;;
        @(blame|bl))
          options="${options} --release --all"
          ;;
        @(build|bi))
          options="${options} --fetch --unpack --setup --build \
                   --check --install --package --ignore-build-no \
                   --quiet --ignore-dependency --output-dir \
                   --ignore-action-errors --ignore-safety \
                   --ignore-check --create-static --package-format \
                   --use-quilt --ignore-sandbox"
          ;;
        @(check))
          options="${options} --component --config"
          ;;
        @(clean))
          options="${options}"
          ;;
        @(configure-pending|cp))
          options="${options} --ignore-dependency --ignore-scom \
                   --ignore-safety --dry-run"
          ;;
        @(delete-cache|dc))
          options="${options}"
          ;;
        @(delta|dt))
          options="${options} --output-dir"
          ;;
        @(disable-repo|dr))
          options="${options}"
          ;;
        @(emerge|em))
          options="${options} --ignore-build-no --quiet --ignore-dependency \
                   --output-dir --ignore-action-errors --ignore safety \
                   --ignore-check --create-static --package-format \
                   --use-quilt --ignore-sandbox --component \
                   --ignore-file-conflicts --ignore-package-conflicts --ignore-scom"
          ;;
        @(enable-repo|er))
          options="${options}"
          ;;
        @(fetch|fc))
          options="${options} --output-dir"
          ;;
        @(graph))
          options="${options} --reporsitory --installed \
                   --ignore-installed --output"
          ;;
        @(help|--help))
          options="${commands}"
          ;;
        @(history|hs))
          options="${options} --last --snapshot --takeback"
          ;;
        @(index|ix))
          options="${options} --absolute-urls --output --skip-sources \
                   --skip-signing"
          ;;
        @(info))
          options="${options} --files --component --files-path --short --xml"
          ;;
        @(install|it))
          options="${options} --ignore-dependency --ignore-scom \
                   --ignore-safety --dry-run --ignore-build-no \
                   --reinstall --ignore-check --ignore-file-conflicts \
                   --ignore-package-conflicts --component --repository \
                   --fetch-only --exclude --exclude-from"
          ;;
        @(list-available|la))
          options="${options} --long --component --uninstalled"
          ;;
        @(list-components|lc))
          options="${options} --long --repository"
          ;;
        @(list-installed|li))
          options="${options} --without-buildno --long --component --install-info"
          ;;
        @(list-newest|ln))
          options="${options} --since --last"
          ;;
        @(list-pending|lp))
          options="${options}"
          ;;
        @(list-repo|lr))
          options="${options}"
          ;;
        @(list-sources|ls))
          options="${options} --long"
          ;;
        @(list-upgrades|lu))
          options="${options} --ignore-build-no --long --component \
                   --install-info"
          ;;
        @(rebuild-db|rdb))
          options="${options} --files"
          ;;
        @(remove|rm))
          options="${options} --ignore-dependency --ignore-scom \
                   --ignore-safety --dry-run --purge --component"
          ;;
        @(remove-repo|rr))
          options="${options}"
          ;;
        @(search|sr))
          options="${options} --language --repository --installdb \
                   --sourcedb --name --summary --description"
          ;;
        @(search-file|sf))
          options="${options} --long --quiet"
          ;;
        @(update-repo|ur))
          options="${options} --force"
          ;;
        @(upgrade|up))
          options="${options} --ignore-dependency --ignore-scom \
                   --ignore-safety --dry-run --ignore-build-no \
                   --security-only --bypass-update-repo \
                   --ignore-file-conflicts --ignore-package-conflicts \
                   --component --repository --fetch-only --exclude --exclude-from"
          ;;
      esac
      COMPREPLY=($(compgen -W "$options" -- $cur))
      return 0;
    else
      case $command in
        @(install|it))
          if [ `ls *.inary 2> /dev/null | wc -l` -gt 0 ]; then
            packages=""
          else
            if `ls /var/lib/inary/index/* &>/dev/null`; then
              packages=`grep -P "<Name>[^\s]*</Name>" /var/lib/inary/index/*/inary-index.xml | gawk -F '>' '{print $2}' | gawk -F '<' '{print $1}' | sort | uniq | tr "\n" " "`
            fi
          fi
          ;;
        @(info))
          if `ls /var/lib/inary/index/* &>/dev/null`; then
            packages=`grep -P "<Name>[^\s]*</Name>" /var/lib/inary/index/*/inary-index.xml | gawk -F '>' '{print $2}' | gawk -F '<' '{print $1}' | sort | uniq | tr "\n" " "`
          fi
          ;;
        @(upgrade|up|remove|rm))
          if `ls /var/lib/inary/index/* &>/dev/null`; then
            packages=`grep -P "<Name>[^\s]*</Name>" /var/lib/inary/package/*/metadata.xml | gawk -F '>' '{print $2}' | gawk -F '<' '{print $1}' | sort | uniq | tr "\n" " "`
          fi
          ;;
      esac
      COMPREPLY=($(compgen -f -W "$packages" -- $cur))
      return 0;
    fi
  fi
  _filedir '@(inary)'
}
complete -F _inary -o filenames inary

_service()
{
  local list

  COMPREPLY=()
  cur="${COMP_WORDS[COMP_CWORD]}"
  cur_num=${#COMP_WORDS[*]}

  if [[ ${cur_num} == 2 ]]; then
    list=`/usr/bin/hav list-apps System.Service`
    COMPREPLY=($(compgen -W "${list} dbus" -- ${cur}))
  elif [[ ${cur_num} -ge 3 ]]; then
    COMPREPLY=($(compgen -W "on off start stop restart reload" -- ${cur}))
  fi
}
complete -F _service service

_hav()
{
  local list command app model

  list=""

  COMPREPLY=()
  cur="${COMP_WORDS[COMP_CWORD]}"
  cur_num=${#COMP_WORDS[*]}

  if [[ ${cur_num} == 2 ]]; then
    COMPREPLY=($(compgen -W "call list-apps list-models list-methods register remove" -- ${cur}))
  elif [[ ${cur_num} == 3 ]]; then
    command=${COMP_WORDS[1]}
    case $command in
      @(call))
        list=`/usr/bin/hav list-apps`
        ;;
      @(list-models|list-methods|register|remove))
        list=`/usr/bin/hav list-apps`
        ;;
    esac
    COMPREPLY=($(compgen -W "${list}" -- ${cur}))
  elif [[ ${cur_num} == 4 ]]; then
    command=${COMP_WORDS[1]}
    app=${COMP_WORDS[2]}
    case $command in
      @(call))
        list=`/usr/bin/hav list-models ${app}`
        ;;
    esac
    COMPREPLY=($(compgen -W "${list}" -- ${cur}))
  elif [[ ${cur_num} == 5 ]]; then
    command=${COMP_WORDS[1]}
    app=${COMP_WORDS[2]}
    model=${COMP_WORDS[3]}
    case $command in
      @(call))
        list=`/usr/bin/hav list-methods ${app} ${model}`
        ;;
    esac
    COMPREPLY=($(compgen -W "${list}" -- ${cur}))
  fi
}
complete -F _hav hav
