#compdef oneclient

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


local arg_oneclient arg_fuse_helper

#
# Generation of hosts completion based on ssh config and ssh known_hosts files
# Based on http://serverfault.com/questions/170346/how-to-edit-command-completion-for-ssh-on-zsh
#
h=()
if [[ -r ~/.ssh/config ]]; then
  h=($h ${${${(@M)${(f)"$(cat ~/.ssh/config)"}:#Host *}#Host }:#*[*?]*})
fi
if [[ -r ~/.ssh/known_hosts ]]; then
  h=($h ${${${(f)"$(cat ~/.ssh/known_hosts{,2} | grep '^[a-zA-Z0-9]' || true)"}%%\ *}%%,*}) 2>/dev/null
fi
if [[ $#h -gt 0 ]]; then
  zstyle ':completion:*:ssh:*' hosts $h
  zstyle ':completion:*:slogin:*' hosts $h
  zstyle ':completion:*:hosts' hosts $h
fi

#
# Generate list of oneclient mountpoints for -u
#
onemounts=($(mount | grep fuse.oneclient | awk '{print $3}'))
if [ $onemounts[(I)$onemounts[-1]] -eq 0 ]; then
  onemounts=""
fi

arg_oneclient=(\
  {-h,--help}'[Show help and exit]' \
  {-V,--version}'[Show current oneclient version and exit]' \
  {-v,--verbose-log-level}'[Specify the log verbosity level]' \
  {-c,--config}'[Specify path to user config file.]: :_files' \
  {-u,--unmount}'[Unmount oneclient and exit]: :{_values "Oneclient mount points" "" $onemounts}' \
  {-i,--insecure}'[Disable verification of server certificate, allows to connect to servers without valid certificate.]' \
  {-H,--host}'[Specify the hostname of the Oneprovider instance to which the oneclient should connect.]: :_hosts' \
  {-P,--port}'[Specify the port to which the oneclient should connect on the Oneprovider.]:_ports' \
  {-t,--token}'[Specify Onedata access token for authentication and authorization.]:token' \
  {-l,--log-path}'[Specify custom path for oneclient logs.]: :{_files -/}' \
  {-r,--override}'[Allows to override selected helper parameters for specific storage.]' \
  '--no-buffer[Disable in-memory cache for input/output data blocks.]' \
  '--provider-timeout[Specify Oneprovider connection timeout in seconds.]:number' \
  '--disable-read-events[Disable reporting of file read events.]' \
  '--force-fullblock-read[Force fullblock read mode.]' \
  '--force-proxy-io[Force proxied access to storage via Oneprovider for all spaces.]' \
  '--force-direct-io[Force direct access to storage for all spaces.]' \
  '--buffer-scheduler-thread-count[Specify number of parallel buffer scheduler threads.]:number' \
  '--communicator-pool-size[Specify number of connections in communicator pool.]:number' \
  '--communicator-thread-count[Specify number of parallel communicator threads.]:number' \
  '--scheduler-thread-count[Specify number of parallel scheduler threads.]:number' \
  '--storage-helper-thread-count[Specify number of parallel storage helper threads.]:number' \
  '--read-buffer-min-size[Specify minimum size in bytes of in-memory cache for input data blocks.]:number' \
  '--read-buffer-max-size[Specify maximum size in bytes of in-memory cache for input data blocks.]:number' \
  '--read-buffer-prefetch-duration[Specify read ahead period in seconds of in-memory cache for input data blocks.]:number' \
  '--write-buffer-min-size[Specify minimum size in bytes of in-memory cache for output data blocks.]:number' \
  '--write-buffer-max-size[Specify maximum size in bytes of in-memory cache for output data blocks.]:number' \
  '--write-buffer-flush-delay[Specify idle period in seconds before flush of in-memory cache for output data blocks.]:number' \
  '--seqrd-prefetch-threshold[Specify linear read prefetch threshold]:number' \
  '--rndrd-prefetch-threshold[Specify random read prefetch threshold]:number' \
  '--metadata-cache-size[Specify maximum number of entries in file metadata cache.]:number' \
  '--io-trace-log[Enable detailed IO trace log.]' \
  '--disable-read-events[Disable reporting of file read events.]' \
  '--no-fullblock-read[Disable fullblock read mode.]' \
  '--rndrd-prefetch-eval-frequency[Number of reads from single file handle which will be skipped before next evaluation of cluster prefetch.]:number' \
  '--rndrd-prefetch-block-threshold[Number of separate blocks after which replication for the file is triggered automatically.]:number' \
  '--rndrd-prefetch-cluster-window[Cluster window size for prefetching in bytes.]:number' \
  '--rndrd-prefetch-cluster-block-threshold[Number of separate blocks in a cluster window around current read.]:number' \
  '--rndrd-prefetch-cluster-window-grow-factor[Prefetch cluster window grow factor.]:number' \
  '--prefetch-mode[Defines the type of block prefetch mode.]:mode' \
  '--cluster-prefetch-threshold-random[Enables random cluster prefetch threshold selection.]' \
  '--readdir-prefetch-size[Specify the size of requests made during readdir prefetch.]:number' \
  '--tag-on-create[Adds name=value extended attribute to each locally created file.]:value' \
  '--tag-on-modify[Adds name=value extended attribute to each locally modified file.]:value' \
  '--space[Allows to specify which space should be mounted by name.]:space' \
  '--space-id[Allows to specify which space should be mounted by space id.]:space' \
  '1: :{_files -/}'\
)

#
# Fuse mount options documentation extracted from:
# - http://linuxcommand.org/man_pages/mount8.html
# - http://man7.org/linux/man-pages/man8/mount.fuse.8.html
#
arg_fuse_helper=(\
  {-f,--foreground}'[Foreground operation]' \
  {-d,--debug}'[Enable debug mode (implies -f)]' \
  {-s,--single-thread}'[Single-threaded operation]' \
  {-o,--opt}'[Pass mount arguments directly to FUSE]: :{_values -s , \
    "FUSE mount options" \
    "allow_other[This option overrides the security measure restricting file access to the filesystem owner, so that all users (including root) can access the files.]" \
    "auto_unmount[This option enables automatic release of the mountpoint if filesystem terminates for any reason.]" \
    "blkdev[Mount a filesystem backed by a block device. The device must be specified with the fsname=NAME option.]" \
    "fsname=[Sets the filesystem source (first field in /etc/mtab). The default is the name of the filesystem process.]" \
    "subtype=[Sets the filesystem type (third field in /etc/mtab). The default is the name of the filesystem process.]" \
    "blksize=[Set the block size for the filesystem. This option is only valid for fuseblk type mounts. The default is 512.]" \
    "default_permissions[This option instructs the kernel to perform its own permission check instead of deferring all permission checking to the filesystem.]" \
    "context=[Allows to assign the entire disk with one security context.]" \
    "fscontext=[Sets the overarching filesystem label to a specific security context.]" \
    "defcontext=[Set the default security context for unlabeled files]" \
    "rootcontext=[Allows to explicitly label the root inode of a FS being mounted before that FS or inode because visable to userspace.]" \
    "max_read=[With this option the maximum size of read operations can be set.]" \
    "user=[Allow an ordinary user to mount  the  file  system.]" \
    "ro[Mount the file system read-only.]" \
    "rw[Mount the file system read-write.]" \
    "suid[Allow set-user-identifier or set-group-identifier bits to take effect.]" \
    "nosuid[Block the operation of suid, and sgid bits.]" \
    "dev[Interpret  character or block special devices on the filesystem.]" \
    "nodev[Do not interpret block special devices on the filesystem.]" \
    "exec[Permit execution of binaries.]" \
    "noexec[Do not allow direct execution of any binaries on the mounted file system.]" \
    "async[All I/O to the file system should be done asynchronously.]" \
    "sync[All I/O to the file system should be done  synchronously.]" \
    "dirsync[All  directory  updates  within the file system should be done synchronously.]" \
    "atime[Update  inode  access  time  for each access. This is the default.]" \
    "noatime[Do  not  update  inode  access  times on this file system.]" \
    }'\
)

_arguments -C -s $arg_oneclient $arg_fuse_helper \
  && ret=0

return ret
