#compdef puppet 
#autoload

#set -x

# puppet zsh completion

local -a _1st_arguments
_1st_arguments=(
  'agent:The puppet agent daemon'
  'apply:Apply Puppet manifests locally'
  'ca:Local Puppet Certificate Authority management.'
  'catalog:Compile, save, view, and convert catalogs'
  'cert:Manage certificates and requests'
  'certificate:Provide access to the CA for certificate management'
  'certificate_request:Manage certificate requests'
  'certificate_revocation_list:Manage the list of revoked certificates'
  'config:Interact with Puppet settings'
  'describe:Display help about resource types'
  'device:Manage remote network devices'
  'doc:Generate Puppet documentation and references'
  'facts:Retrieve and store facts'
  'file:Retrieve and store files in a filebucket'
  'filebucket:Store and retrieve files in a filebucket'
  'help:Display Puppet help'
  'inspect:Send an inspection report'
  'instrumentation_data:Manage instrumentation listener accumulated data'
  'instrumentation_listener:Manage instrumentation listeners'
  'instrumentation_probe:Manage instrumentation probes'
  'key:Create, save, and remove certificate keys'
  'kick:Remotely control puppet agent'
  'man:Display Puppet manual pages'
  'master:The puppet master daemon'
  'module:Creates, installs and searches for modules on the Puppet Forge'
  'node:View and manage node definitions'
  'parser:Interact directly with the parser'
  'plugin:Interact with the Puppet plugin system'
  'queue:Deprecated queuing daemon for asynchronous storeconfigs'
  'report:Create, display, and submit reports'
  'resource:The resource abstraction layer shell'
  'resource_type:View classes, defined resource types, and nodes from all manifests'
  'secret_agent:Mimics puppet agent'
  'status:View puppet server status'
)

local -a _agent_arguments
_agent_arguments=(
  '--certname:<name> Set the certname of the client'
  '-D:Send process to background (daemonize)'
  '--daemonize:Send process to background (daemonize)'
  '--no-daemonize:Do not send process to background'
  '-d:Enable full debugging'
  '--debug:Enable full debugging'
  '--detailed-exitcodes:Provide transaction information via exit codes'
  '--digest:<digest> Change the certificate fingerprinting digest algorithm'
  '--disable:<message> Disable working on the local system'
  '--enable:Enable working on the local system'
  '--fingerprint:Display the current certificate or certificate signing request fingerprint and then exit'
  '-h:Print this help message'
  '--help:Print this help message'
  '-l:syslog|<file>|console Where to send messages'
  '--logdest:syslog|<file>|console Where to send messages'
  '--no-client:Do not create a config client'
  '--masterport:The port on which to contact the puppet master'
  '--noop:Use "noop" mode where the daemon runs in a no-op or dry-run mode'
  '-o:Run the configuration once'
  '--onetime:Run the configuration once'
  '-t:Enable the most common options used for testing'
  '--test:Enable the most common options used for testing'
  '-v:Turn on verbose reporting'
  '--verbose:Turn on verbose reporting'
  '-V:Print the puppet version number and exit'
  '--version:Print the puppet version number and exit'
  '-w:This option only matters for daemons that do not yet have certificates'
  '--waitforcert:<seconds> This option only matters for daemons that do not yet have certificates'
)

local -a _apply_arguments
_apply_arguments=(
  '-h:Print this help message'
  '--help:Print this help message'
  '-d:Enable full debugging'
  '--debug:Enable full debugging'
  '-v:Print extra information'
  '--verbose:Print extra information'
  '-e:Execute a specific piece of Puppet code'
  '--execute:Execute a specific piece of Puppet code'
  '--detailed-exitcodes:'
  '-l:Where to send messages'
  '--logdest:<file> Where to send messages'
  '--noop:Use "noop" mode where Puppet runs in a no-op or dry-run mode'
  '--catalog:<catalog>: Apply a JSON catalog (such as one generated with "puppet master --compile)"'
  '--write-catalog-summary:<file> After compiling the catalog saves the resource list and classes list'
)

local -a _ca_arguments
_ca_arguments=(
  'destroy:undocumented action'
  'fingerprint:undocumented action'
  'generate:undocumented action'
  'list:List certificates and/or certificate requests'
  'print:undocumented action'
  'revoke:undocumented action'
  'sign:undocumented action'
  'verify:undocumented action'
)

local -a _catalog_arguments
_catalog_arguments=(
  'apply:Find and apply a catalog'
  "download:Download this node's catalog from the puppet master server"
  'find:Retrieve the catalog for a node'
  'info:Print the default terminus class for this face'
  'save:API only: create or overwrite an object'
  'select:Retrieve a catalog and filter it for resources of a given type'
  '--render-as:FORMAT The rendering format to use'
  '--verbose:Whether to log verbosely'
  '--debug:Whether to log debug information'
  '--extra HASH:Extra arguments to pass to the indirection request'
  '--terminus: TERMINUS The indirector terminus to use'
)

local -a _cert_arguments
_cert_arguments=(
  "clean:Revoke a host's certificate (if applicable) and remove all files related to that host from puppet cert's storage"
  "fingerprint:Print the DIGEST (defaults to the signing algorithm) fingerprint of a host's certificate"
  'generate:Generate a certificate for a named client'
  'list:List outstanding certificate requests'
  "print:Print the full-text version of a host's certificate."
  'revoke:Revoke the certificate of a client'
  'sign:Sign an outstanding certificate request'
  'verify:Verify the named certificate against the local CA certificate'
  'reinventory:Build an inventory of the issued certificates'
  '-h:Print this help message'
  '--help:Print this help message'
  '-V:Print the puppet version number and exit'
  '--version:Print the puppet version number and exit'
  '--verbose:Whether to log verbosely'
  '--debug:Whether to log debug information'
  '--digest:Set the digest for fingerprinting'
)

local -a _certificate_arguments
_certificate_arguments=(
  'destroy:Delete a certificate'
  'find:Retrieve a certificate'
  'generate:Generate a new certificate signing request'
  'info:Print the default terminus class for this face'
  'list:List all certificate signing requests'
  'sign:Sign a certificate signing request for HOST'
  '--render-as:FORMAT The rendering format to use'
  '--verbose:Whether to log verbosely'
  '--debug:Whether to log debug information'
  '--ca-location: LOCATION Which certificate authority to use (local or remote)'
  '--extra HASH:Extra arguments to pass to the indirection request'
  '--terminus: TERMINUS The indirector terminus to use'
)

local -a _certificate_revocation_list_arguments
_certificate_revocation_list_arguments=(
  destroy    Delete the certificate revocation list.
  find       Retrieve the certificate revocation list.
  info       Print the default terminus class for this face.
  save       Invalid for this subcommand.
  search     Invalid for this subcommand.
)

__task_list ()
{
    local expl
    declare -a tasks

    tasks=(agent apply ca catalog cert certificate certificate_revocation_list config describe device doc facts file filebucket help inspect instrumentation_data instrumentation_listener instrumentation_probe key kick man master module node parser plugin queue report resource resource_type secret_agent status)

    _wanted tasks expl 'help' compadd $tasks
}

__puppet-agent ()
{
  local curcontext="$curcontext" state line
  typeset -A opt_args

  _arguments -C \
    ':command:->command' \
    '*::options:->options'

  case $state in
    (command)
      _describe -t commands "gem subcommand" _agent_arguments
      return
    ;;
    esac
}

__puppet-apply ()
{
  local curcontext="$curcontext" state line
  typeset -A opt_args

  _arguments -C \
    ':command:->command' \
    '*::options:->options'

  case $state in
    (command)
      _describe -t commands "gem subcommand" _apply_arguments
      return
    ;;
  esac
}

__puppet-ca ()
{
  local curcontext="$curcontext" state line
  typeset -A opt_args

  _arguments -C \
    ':command:->command' \
    '*::options:->options'

  case $state in
    (command)
      _describe -t commands "gem subcommand" _ca_arguments
      return
    ;;
  esac
}

__puppet-catalog ()
{
  local curcontext="$curcontext" state line
  typeset -A opt_args

  _arguments -C \
    ':command:->command' \
    '*::options:->options'

  case $state in
    (command)
      _describe -t commands "gem subcommand" _catalog_arguments
      return
    ;;
  esac
}

__puppet-cert ()
{
  local curcontext="$curcontext" state line
  typeset -A opt_args

  _arguments -C \
    ':command:->command' \
    '*::options:->options'

  case $state in
    (command)
      _describe -t commands "gem subcommand" _cert_arguments
      return
    ;;
  esac
}

__puppet-certificate ()
{
  local curcontext="$curcontext" state line
  typeset -A opt_args

  _arguments -C \
    ':command:->command' \
    '*::options:->options'

  case $state in
    (command)
      _describe -t commands "gem subcommand" _certificate_arguments
      return
    ;;
  esac
}



local expl
#local -a boxes installed_boxes

local curcontext="$curcontext" state line
typeset -A opt_args

_arguments -C \
    ':command:->command' \
    '*::options:->options'

case $state in
  (command)
      _describe -t commands "gem subcommand" _1st_arguments
      return
  ;;

  (options)
    case $line[1] in
      # Auto-complete help for top-level command sub-commands e.g. puppet help agent, puppet help apply.
      (help)
         _arguments ':feature:__task_list' 
      ;;

      # Display sub-commands for puppet agent.
      (agent)
          __puppet-agent
      ;;

      # Display sub-commands for puppet apply.
      (apply)
          __puppet-apply
      ;;

      # Display sub-commands for puppet ca.
      (ca)
          __puppet-ca
      ;;

      # Display sub-commands for puppet catalog.
      (catalog)
          __puppet-catalog
      ;;

      # Display sub-commands for puppet cert.
      (cert)
          __puppet-cert
      ;;

      # Display sub-commands for puppet certificate.
      (certificate)
          __puppet-certificate
      ;;
    esac
  ;;
esac
