#compdef isi_classic

# Copyright C 2002-2010 by Isilon Systems, Inc. All rights not expressly
# granted herein are reserved.
# Created in the United States of America.
# 
# This digital media is protected by U.S. and international copyright and
# intellectual property laws. Unless otherwise specified, all information
# and screens appearing as part of this digital medium, including
# software, services, documents, text, images, icons, and logos design;
# the selection, assembly, arrangement, and design thereof; and the code
# that enables its presentation, are the sole property of Isilon Systems,
# Inc.
# 
# Except as otherwise required by applicable law, no part of any
# copyrighted material may be reproduced, modified, translated,
# distributed, published, or transmitted by any means, electronic or
# mechanical, for any purpose, without the prior written consent of Isilon
# Systems. 
#  
# Isilon and Isilon Systems are registered trademarks of Isilon Systems,
# Inc.  Legion is a trademark of Isilon Systems, Inc.  All other
# trademarks and registered trademarks are the property of their
# respective holders.

# redefine _isi

_isi_classic () {
  _arguments \
    - help \
      '-h' \
    - nonhelp \
      '*::isi_classic command:_isi_command'
}

(( $+functions[_isi_command] )) ||
_isi_command() {
  if (( ! $+_isi_cmds )); then
    typeset -gA _isi_cmds
    _isi_cmds=(
       $(/usr/bin/isi_classic -l 2>&1)
    )
  fi
  if (( CURRENT == 1 )); then
    _tags commands && { compadd "$@" -k _isi_cmds || compadd "$@" ${(kv)=_isi_cmds} }
  else
    local curcontext="$curcontext"
    cmd="${${(k)_isi_cmds[(R)* $words[1] *]}:-${(k)_isi_cmds[(i)$words[1]]}}"
    if (( $#cmd )); then
      for item in [ auth smb nfs snapshot quota ]; do
          if [[ $cmd == $item ]]; then
            curcontext="${curcontext%:*:*}:isi_classic-${cmd}:"
            #echo "calling _isi_classic_$cmd"
            _isi_classic_$cmd
            return 1
          fi
      done
      
      curcontext="${curcontext%:*:*}:isi-${cmd}:"
      _isi_$cmd
    else
      _message "unknown isi command: $words[1]"
    fi
  fi
}

(( $+functions[_isi_config] )) ||
_isi_config() {
}

(( $+functions[_isi_smartpools] )) ||
_isi_smartpools() {
  if (( CURRENT == 2 )); then
    _tags values && { compadd $@ apply }
  else
    cmd=$words[2]
    if [[ $cmd == "apply" ]]; then
      _isi_apply
    fi
  fi
}

(( $+functions[_isi_apply] )) ||
_isi_apply() {
  _arguments : \
    '-v[print attributes to set]' \
    '-n[calculate but set no attributs]' \
    '-r[recursively enter all subdirectories]' \
    '-R[recursively enter all subdirectories]' \
    '-p[specify path]:path:_isi_path' \
    '*::path:_isi_path'
}

(( $+functions[_isi_set] )) ||
_isi_set() {
  _arguments \
    '-f[ignore errors]' \
    '-n[no changes]' \
    '-r[force restripe]' \
    '-v[list files being protected]' \
    '-R[recursively enter all subdirectories]' \
    '-p[set protection level]:protect:_isi_protect' \
    '-c[set coalescing]:coalesce:_isi_coalesce' \
    '-l[set performance]:performance:_isi_performance' \
    '*::path:_isi_path'
}

(( $+functions[_isi_devices] )) ||
_isi_devices() {
  _arguments \
    '-a[action]:action:_isi_dev_actions' \
    '-d[device <node lnn>:<drive>]:device:_isi_node:' \
}

(( $+functions[_isi_get] )) ||
_isi_get() {
  _arguments \
    '-a[include . and .. entries]' \
    '-D[include verbose (debug) output]' \
    '-DD[include extremely verbose (debug) output]' \
    '-d[list directories as plain files]' \
    '-R[recursively enter all subdirectories]' \
    '*::path:_isi_path'
}

(( $+functions[_isi_status] )) ||
_isi_status() {
  _arguments \
    '-q[omit (quiet) protection operations]' \
    '-r[show raw storage values]' \
    '-w[do not truncate output lines (wide view)]' \
    '-D[include verbose (debug) output]' \
    '-n[show node status]::node status:_isi_node' \
    '-d[(diskpool_name) show diskpool status]' \
    '-v[show node status along with diskpool status]'
}

(( $+functions[_isi_perfstat] )) ||
_isi_perfstat() {
}

(( $+functions[_isi_batterystatus] )) ||
_isi_batterystatus() {
}

# XXX ftp has many subcommands, complete just on --help for now
(( $+functions[_isi_ftp] )) ||
_isi_ftp() {
	_arguments '--help'
}

# XXX email has many subcommands, complete just on --help for now
(( $+functions[_isi_email] )) ||
_isi_email() {
	_arguments '--help'
}

(( $+functions[_isi_services] )) ||
_isi_services() {
  _arguments \
    - list \
      '-l[list services]' \
    - listall \
      '-a[list all services]' \
    - doservice \
      ':services:_isi_service' \
      ':enabledisable:_isi_enabledisable'
}

(( $+functions[_isi_servicelight] )) ||
_isi_servicelight() {
  if (( CURRENT == 2 )); then
    _tags values && { compadd $@ on off status }
  fi
}

(( $+functions[__isi_logview] )) ||
_isi_logview() {
  _arguments \
    '*::logfile:_isi_logfile'
}

(( $+functions[_isi_service] )) ||
_isi_service() {
  typeset -gA _isi_servs
  _isi_servs=(
    ${(f)${(F)${${(M)${(f)"$(_call_program commands isi services 2>&1)"}:# *}/(#b) #([a-z0-9_]##) */$match[1]
    }}}
  )
  _tags commands && { compadd "$@" -k _isi_servs || compadd "$@" ${(kv)=_isi_servs} }
}

(( $+functions[_isi_enabledisable] )) ||
_isi_enabledisable() {
    _tags values && { compadd $@ enable disable }
}

(( $+functions[_isi_node] )) ||
_isi_node() {
    _tags values && { compadd $@ `/usr/local/share/zsh/site-functions/list-nodes` }
}

(( $+functions[_isi_coalesce] )) ||
_isi_coalesce() {
    _tags values && { compadd $@ on off }
}

(( $+functions[_isi_protect] )) ||
_isi_protect() {
    _tags values && { compadd $@ `/usr/local/share/zsh/site-functions/list-protection $words[CURRENT]` }
}

(( $+functions[_isi_performance] )) ||
_isi_performance() {
    _tags values && { compadd $@ concurrency streaming }
}

(( $+functions[_isi_dev_actions] )) ||
_isi_dev_actions() {
    _tags values && { compadd $@ `/usr/local/share/zsh/site-functions/list-dev-actions $words[CURRENT]` }
}

(( $+functions[_isi_path] )) ||
_isi_path() {
    SAVED=$IFS
    IFS=`echo "\n\r\t"`
    _tags values && { compadd -S "" $@ `/usr/local/share/zsh/site-functions/filename-complete $words[CURRENT] /ifs` }
    IFS=$SAVED
}

(( $+functions[_isi_logfile] )) ||
_isi_logfile() {
    SAVED=$IFS
    IFS=`echo "\n\r\t"`
    _tags values && { compadd -S "" $@ `/usr/local/share/zsh/site-functions/filename-complete $words[CURRENT] /var/log` }
    IFS=$SAVED
}

(( $+functions[_isi_update] )) ||
_isi_update() {
  _arguments \
    '-r[to do a rolling update]' \
    '--manual[ask for confirmation between rolling reboots]' \
    '--drain-time=[time to wait for connection drain]' \
    '-d[disable DON/storage expansion node check]' \
    ':file:_files'
}

(( $+functions[_isi_flexprotect] )) ||
_isi_flexprotect() {
}

(( $+functions[_isi_license] )) ||
_isi_license() {
  if (( CURRENT == 2 )); then
    _tags values && { compadd $@ status activate unconfigure }
  fi
}

(( $+functions[_isi_pkg] )) ||
_isi_pkg() {
  if (( CURRENT == 2 )); then
    _tags values && { compadd $@ create info install delete }
  elif (( CURRENT == 3 )); then
    cmd=$words[2]
    if (( $#cmd )); then
      if [[ $cmd == "create" || $cmd == "install" ]]; then
        _arguments '*::path:_isi_path'
      else
	_tags values && { compadd $@ `/usr/local/share/zsh/site-functions/list-patches` }
      fi
    fi
  fi
}

(( $+functions[_isi_version] )) ||
_isi_version() {
  if (( CURRENT == 2 )); then
    _tags values && { compadd $@ osversion osbuild osrelease ostype osreldate osrevision copyright }
  fi
}

(( $+functions[_isi_readonly] )) ||
_isi_readonly() {
  if (( CURRENT == 2 )); then
    _tags values && { compadd $@ on off show }
  fi
}

# Extracts the list of known devices, as described in devices.xml,
# via the hidden "isi firmware devices" command
(( $+functions[_isi_list_firmware_devices] )) ||
_isi_list_firmware_devices() {
    _tags values && { compadd $@ `isi firmware devices | awk '{ if (go) print $2 } /^---/ { go = 1 }' | sort | uniq` }
}

# Extracts the list of known device types, as described in devices.xml,
# via the hidden "isi firmware devices" command
(( $+functions[_isi_list_firmware_types] )) ||
_isi_list_firmware_types() {
    _tags values && { compadd $@ `isi firmware devices | awk '{ if (go) print $3 } /^---/ { go = 1 }' | sort | uniq` }
}

# Extracts the list of known node lnns in the cluster via isi_nodes
(( $+functions[_isi_list_nodes] )) ||
_isi_list_nodes() {
    _tags values && { compadd $@ `isi_nodes %{lnn}` }
}

# Sets argument options for "isi firmware {status,update}" commands.
(( $+functions[_isi_firmware_status_update_options] )) ||
_isi_firmware_status_update_options() {
  _arguments \
    '--verbose[Verbose output]' \
    '--save[Save local info to a file (status command only)]' \
    '(--exclude-device)*--include-device=[Include the specified device]:device:_isi_list_firmware_devices' \
    '(--include-device)*--exclude-device=[Exclude the specified device]:exclude-device:_isi_list_firmware_devices' \
    '(--exclude-type)*--include-type=[Include the specified device type]:type:_isi_list_firmware_types' \
    '(--include-type)*--exclude-type=[Exclude the specified device type]:exclude-type:_isi_list_firmware_types' \
    '(--exclude-nodes --local --storage --diskless)*--include-nodes=[Include the specified nodes]:nodes:_isi_list_nodes' \
    '(--include-nodes --local --storage --diskless)*--exclude-nodes=[Exclude the specified nodes]:exclude-nodes:_isi_list_nodes' \
    '(--include-nodes --exclude-nodes --storage --diskless)--local[Include the local node only]' \
    '(--include-nodes --exclude-nodes --local --diskless)--storage[Include storage nodes only]' \
    '(--include-nodes --exclude-nodes --local --storage)--diskless[Include diskless nodes only]'
}

# Sets argument options for "isi firmware package" command.
(( $+functions[_isi_firmware_package_options] )) ||
_isi_firmware_package_options() {
  _arguments \
    '(--exclude-nodes --local --storage --diskless)*--include-nodes=[Include the specified nodes]:nodes:_isi_list_nodes' \
    '(--include-nodes --local --storage --diskless)*--exclude-nodes=[Exclude the specified nodes]:exclude-nodes:_isi_list_nodes' \
    '(--include-nodes --exclude-nodes --storage --diskless)--local[Include the local node only]' \
    '(--include-nodes --exclude-nodes --local --diskless)--storage[Include storage nodes only]' \
    '(--include-nodes --exclude-nodes --local --storage)--diskless[Include diskless nodes only]'
}

# Main "isi firmware" command completion code. Publishes
# completions for publicly advertised sub-commands, as well
# as their options/arguments.
(( $+functions[_isi_firmware] )) ||
_isi_firmware() {
  if (( CURRENT == 2 )); then
    _tags values && { compadd $@ status update package }
  else
    local cmd=${words[2]}
    (( CURRENT-- ))
    shift words
    if [[ $cmd == status || $cmd == update ]]; then
      _isi_firmware_status_update_options
    elif [[ $cmd == package || $cmd == images ]]; then
      _isi_firmware_package_options
    fi
  fi
}

(( $+functions[__isi_snmp] )) ||
_isi_snmp() {
  if (( CURRENT == 2 )); then
    _tags values && {compadd $@ list}
    _arguments \
      '--syslocation=[system location sysLocation.0]' \
      '--syscontact=[system contact sysContact.0]' \
      '--protocols=[SNMP protocols ("v1/v2c" | "v3" | "all")]' \
      {-c,--rocommunity}'=[read-only community name]' \
      {-u,--v3-rouser}'=[SNMP v3 read-only user (securityName)]' \
      {-p,--v3-password}'=[SNMP v3 auth password]' \
      {-h,--help}'[Print usage help and exit]'
  else
    local cmd=${words[2]}
    (( CURRENT-- ))
    shift words
    if [[ $cmd == list ]]; then
      _arguments \
        '--help[Print usage help and exit]'
    fi
  fi
}

(( $+functions[_isi_fc] )) ||
_isi_fc() {
  if (( CURRENT == 2 )); then
    _tags values && { compadd $@ disable enable list set }
  else
    local cmd=${words[2]}
    (( CURRENT-- ))
    shift words
    if [[ $cmd == disable ]]; then
      curcontext="${curcontext%:*:*}:isi-fc-disable:"
      _isi_fc_disable
    elif [[ $cmd == enable ]]; then
      curcontext="${curcontext%:*:*}:isi-fc-enable:"
      _isi_fc_enable
    elif [[ $cmd == list ]]; then
      curcontext="${curcontext%:*:*}:isi-fc-list:"
      _isi_fc_list
    elif [[ $cmd == set ]]; then
      curcontext="${curcontext%:*:*}:isi-fc-set:"
      _isi_fc_set
    else
      _message "unknown isi ndmp command: $words[1]"
    fi
  fi
}

(( $+functions[_isi_fc_list] )) ||
_isi_fc_list() {
  _tags values && { compadd $@ --help }
  _arguments \
    '--port=[port to list]:port_id:_isi_fc_port_list' \
    '--node=[list all ports on node]' \
    '--help[Print usage help and exit]'
}

(( $+functions[_isi_fc_port_list] )) ||
_isi_fc_port_list() {
     _tags values && { compadd $@ `isi fc list | awk '{ if (FNR > 1) print $1}'` }
}

(( $+functions[_isi_fc_topology_list] )) ||
_isi_fc_topology_list() {
     _tags values && { compadd $@ auto loop ptp }
}

(( $+functions[_isi_fc_rate_list] )) ||
_isi_fc_rate_list() {
     _tags values && { compadd $@ auto 1 2 4 }
}

(( $+functions[_isi_fc_disable] )) ||
_isi_fc_disable() {
  _tags values && { compadd $@ --help }
  _arguments \
    '--port=[port to disable]:port_id:_isi_fc_port_list' \
    '--help[Print usage help and exit]'
}

(( $+functions[_isi_fc_enable] )) ||
_isi_fc_enable() {
  _tags values && { compadd $@ --help }
  _arguments \
    '--port=[port to enable]:port_id:_isi_fc_port_list' \
    '--help[Print usage help and exit]'
}

(( $+functions[_isi_fc_set] )) ||
_isi_fc_set() {
  _tags values && { compadd $@ --help }
  _arguments \
    '--port=[port to set]:port_id:_isi_fc_port_list' \
    '--wwnn=[world wide node name]' \
    '--wwpn=[world wide port name]' \
    '--topology=[topology]:topology:_isi_fc_topology_list' \
    '--rate=[rate]:rate:_isi_fc_rate_list' \
    '--help[Print usage help and exit]'
}

(( $+functions[_isi_tape] )) ||
_isi_tape() {
  if (( CURRENT == 2 )); then
    _tags values && { compadd $@ delete list rename rescan }
  else
    local cmd=${words[2]}
    (( CURRENT-- ))
    shift words
    if [[ $cmd == delete ]]; then
      curcontext="${curcontext%:*:*}:isi-tape-delete:"
      _isi_tape_delete
    elif [[ $cmd == list ]]; then
      curcontext="${curcontext%:*:*}:isi-tape-list:"
      _isi_tape_list
    elif [[ $cmd == rename ]]; then
      curcontext="${curcontext%:*:*}:isi-tape-rename:"
      _isi_tape_rename
    elif [[ $cmd == rescan ]]; then
      curcontext="${curcontext%:*:*}:isi-tape-rescan:"
      _isi_tape_rescan
    else
      _message "unknown isi ndmp command: $words[1]"
    fi
  fi
}

(( $+functions[_isi_tape_device_list] )) ||
_isi_tape_device_list() {
     _tags values && { compadd $@ `isi tape list --tape | awk '{ if (FNR > 2) print $1}'` }
     _tags values && { compadd $@ `isi tape list --mc | awk '{ if (FNR > 2) print $1}'` }
}

(( $+functions[_isi_tape_list] )) ||
_isi_tape_list() {
  _tags values && { compadd $@ --help }
  _arguments \
    '--verbose[Show device path information]' \
    '--node=[List only devices accessible from node]' \
    '--tape[List only tape devices]' \
    '--mc[List only media changer devices]' \
    '--devname=[device name]:devname:_isi_tape_device_list' \
    '--help[Print usage help and exit]'
}

(( $+functions[_isi_tape_delete] )) ||
_isi_tape_delete() {
  _tags values && { compadd $@ --help }
  _arguments \
    '--all[delete all devices]' \
    '--devname=[name of device to delete]:devname:_isi_tape_device_list' \
    '--help[Print usage help and exit]'
}

(( $+functions[_isi_tape_rename] )) ||
_isi_tape_rename() {
  _tags values && { compadd $@ --help }
  _arguments \
    '--devname=[name of device to rename]:devname:_isi_tape_device_list' \
    '--rename=[new device name]' \
    '--help[Print usage help and exit]'
}

(( $+functions[_isi_tape_rescan] )) ||
_isi_tape_rescan() {
  _tags values && { compadd $@ --help }
  _arguments \
    '--node=[node to rescan]' \
    '--port=[port to rescan]' \
    '--reconcile[delete inaccessible devices/paths]' \
    '--help[Print usage help and exit]'
}

(( $+functions[_isi_job] )) ||
_isi_job() {
  if (( CURRENT == 2 )); then
    _tags values && { compadd $@ `isi job -h | awk '!/sub-commands/ && /\[/{ print $1 }'` }
  else
    local cmd=${words[2]}
    (( CURRENT-- ))
    shift words
    if [[ $cmd == schedule ]]; then
      curcontext="${curcontext%:*:*}:isi-job-schedule:"
      _isi_job_schedule
    elif [[ $cmd == policy ]]; then
      curcontext="${curcontext%:*:*}:isi-job-policy:"
      _isi_job_policy
    elif [[ $cmd == start ]]; then
      curcontext="${curcontext%:*:*}:isi-job-start:"
      _isi_job_start
    elif [[ $cmd == stop ]]; then
      curcontext="${curcontext%:*:*}:isi-job-stop:"
      _isi_job_stop
    elif [[ $cmd == pause ]]; then
      curcontext="${curcontext%:*:*}:isi-job-pause:"
      _isi_job_pause
    elif [[ $cmd == resume ]]; then
      curcontext="${curcontext%:*:*}:isi-job-resume:"
      _isi_job_resume
    elif [[ $cmd == cancel ]]; then
      curcontext="${curcontext%:*:*}:isi-job-cancel:"
      _isi_job_cancel
    elif [[ $cmd == update ]]; then
      curcontext="${curcontext%:*:*}:isi-job-update:"
      _isi_job_update
    fi
  fi
}

(( $+functions[_isi_job_operations] )) ||
_isi_job_operations() {
    if (( CURRENT == 2 )); then
        _tags values && { compadd $@ `isi job list | tail +4 | awk '/^[A-Z]/{ print tolower($1) }'` }
    fi
}

(( $+functions[_isi_job_start] )) ||
_isi_job_start() {
  if (( CURRENT == 2 )); then
  _arguments : \
        '-j[Job name]' \
        '--job[Job name]'

    _isi_job_operations
  else
    local cmd=${words[2]}
    if [[ $cmd == "--job" || $cmd == "-j" ]]; then
        (( CURRENT-- ))
        shift words
        curcontext="${curcontext%:*:*}:isi-job-operations:"
        _isi_job_operations
    elif [[ $cmd == "treedelete" || $cmd == "TreeDelete" ]]; then
        (( CURRENT-- ))
        shift words
        curcontext="${curcontext%:*:*}:isi-job-treedelete:"
        _isi_job_treedelete
    fi
  fi
}

(( $+functions[_isi_job_treedelete] )) ||
_isi_job_treedelete() {
    _arguments : \
         '--path[specify path]:path:_isi_path' \
          '*::path:_isi_path'
}

(( $+functions[_isi_job_stop] )) ||
_isi_job_stop() {
    if (( CURRENT == 2 )); then
        _isi_job_operations
    fi
}

(( $+functions[_isi_job_pause] )) ||
_isi_job_pause() {
    if (( CURRENT == 2 )); then
        _isi_job_operations
    fi
}

(( $+functions[_isi_job_resume] )) ||
_isi_job_resume() {
    if (( CURRENT == 2 )); then
        _isi_job_operations
    fi
}
(( $+functions[_isi_job_cancel] )) ||
_isi_job_cancel() {
    if (( CURRENT == 2 )); then
        _isi_job_operations
    fi
}

(( $+functions[_isi_job_update] )) ||
_isi_job_update() {
    if (( CURRENT == 2 )); then
        _isi_job_operations
    fi
}

(( $+functions[_isi_job_schedule] )) ||
_isi_job_schedule() {
  if (( CURRENT == 2 )); then
    _tags values && { compadd $@ `isi job schedule -h | awk '!/sub-commands/ && /\[/{ print $1 }'` }
  else
    local cmd=${words[2]}
    (( CURRENT-- ))
    shift words
    if [[ $cmd == list ]]; then
      curcontext="${curcontext%:*:*}:isi-job-schedule-list:"
      _isi_job_schedule_list
    elif [[ $cmd == start ]]; then
      curcontext="${curcontext%:*:*}:isi-job-schedule-set:"
      _isi_job_schedule_set
    elif [[ $cmd == delete ]]; then
      curcontext="${curcontext%:*:*}:isi-job-schedule-delete:"
      _isi_job_schedule_delete
    fi
  fi
}

(( $+functions[_isi_job_schedule_list] )) ||
_isi_job_schedule_list() {
  _arguments \
    '--verbose[Verbose output]' \
}

(( $+functions[_isi_job_schedule_set] )) ||
_isi_job_schedule_set() {
}

(( $+functions[_isi_job_schedule_delete] )) ||
_isi_job_schedule_delete() {
}

(( $+functions[_isi_job_policy] )) ||
_isi_job_policy() {
     _tags values && { compadd $@ list ls create new set modify delete rm remove }
}

_isi "$@" 
