#compdef pot

: ${POT_FS_ROOT:=$( pot config -qg fs_root )}

_pot_pots() {
        _values "pot pots" ${${(f)"$(${service} ls -qp)"}%% *}
}

_pot_run_pots() {
        _values "pot pots" ${${(f)"$(${service} ps -q)"}%% *}
}

_pot_bases() {
        _values "pot pots" ${${(f)"$(${service} ls -qb)"}%% *}
}

_pot_fscomps() {
        _values "pot flavors" ${${(f)"$(${service} ls -qf)"}%% *}
}

_pot_bridges() {
        _values "pot bridges" ${${(f)"$(${service} ls -qB)"}%% *}
}

_pot_flavours() {
        _values "pot flavors" ${${(f)"$(${service} ls -qF)"}%% *}
}

_pot_attributes() {
	_values "pot attributes" 'start-at-boot' 'early-start-at-boot' 'persistent' 'no-rc-script' 'prunable' 'localhost-tunnel' 'enforce_statfs' 'mount' 'fdescfs' 'linprocfs' 'nullfs' 'procfs' 'tmpfs' 'zfs' 'children'
}

_pot_network_type() {
	_values "pot network type" "inherit" "alias" "public-bridge" "private-bridge" "private-bridge"
}

_pot_network_stack_type() {
	_values "pot network stack type" "ipv4" "ipv6" "dual"
}

_pot() {
	_arguments \
		'1: :_pot_cmds' \
		'*:: :->args'

	case $state in
		args)
			case $words[1] in
				init)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]'
					;;
				vnet-start)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-B[bridge name]:bridge name:_pot_bridges'
					;;
				config)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-q[Quiet output]' \
						'-g[Element name]:config element name:(fs_root zfs_root gateway syslogd pot_prefix fscomp_prefix network_stack)'
					;;
				de-init)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-f[Force stop of all running pots]'
					;;
				version|ps)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-q[Quiet output]'
					;;
				list|ls)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-q[Quiet output]' \
						'-p[List pots]' \
						'-b[List bases]' \
						'-f[List fscomps]' \
						'-B[List bridges]' \
						'-F[List flavours]' \
						'-a[List them all]'
					;;
				info)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-q[Quiet output]' \
						'-p[pot name]:pot name:_pot_pots' \
						'-B[bridge name]:bridge name:_pot_bridges' \
						'-r[Check only if the pos is running]' \
						'-s[List only the available snapshots of the pot]' \
						'-E[Print few pot information as environment variables]'
					;;
				show)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-q[Quiet output]' \
						'-a[All pots]' \
						'-r[All running pots]' \
						'-p[pot name]:pot name:_pot_pots'
					;;
				create-base)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-r[Release number]:supported releases:_normal' \
						'-b[base name]:base name:_normal'
					;;
				create-fscomp)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-f[fscomp name]:fscomp name:_normal'
					;;
				create-private-bridge)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-S[host number]:host number:_normal' \
						'-B[bridge name]:bridge name:_normal'
					;;
				create)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-k[keep pot if it fails]' \
						'-t[pot type]:pot type:(single multi)' \
						'-N[network type]:network type:_pot_network_type' \
						'-p[pot name]:pot name:_normal' \
						'-P[pot reference]:pot reference name:_pot_pots' \
						'-b[base version]:base version:_pot_bases' \
						'-l[pot level]:level:(0 1 2)' \
						'-t[pot type]:type:(multi single)' \
						'*-i[network config]::_normal' \
						'-d[dns type]:dns types:(inherit pot off custom:)' \
						'-B[bridge name]:bridge name:_pot_bridges' \
						'-S[network stack]:network stack:_pot_network_stack_type' \
						'*-f[flavour name]:flavour name:_pot_flavours'
					;;
				clone-fscomp)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-f[fscomp name]::_normal' \
						'-F[fscomp reference]:fscomp reference name:_pot_fscomps'
					;;
				clone)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-k[keep pot if it fails]' \
						'-p[pot name]::_normal' \
						'-P[pot reference]:pot reference name:_pot_pots' \
						'*-f[flavour name]:flavour name:_pot_flavours'
						'-N[network type]:network type:_pot_network_type' \
						'-i[network config]::_normal' \
						'-B[bridge name]:bridge name:_pot_bridges' \
						'-S[network stack]:network stack:_pot_network_stack_type' \
						'-F[force snapshot of the pot reference]'
					;;
				rename)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-n[pot new name]::_normal' \
						'-p[pot old name]:pot old name:_pot_pots'
					;;
				destroy)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-q[Quiet output]' \
						'-F[Force the pot to stop]' \
						'-p[pot name]:pot name:_pot_pots' \
						'-b[base name]:base name:_pot_bases' \
						'-f[fscomp name]:fscomp name:_pot_fscomps' \
						'-B[bridge name]:bridge name:_pot_bridges' \
						'-r[Recursive destroying]'
					;;
				prune)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-q[Quiet outpu]' \
						'-n[dry-run]'
					;;
				copy-in)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-F[Force with running pots]' \
						'-p[pot name]:pot name:_pot_pots' \
						'-s[source]:source:_normal' \
						'-d[destination]:destination:_normal'
					;;
				mount-in)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-p[pot name]:pot name:_pot_pots' \
						'-m[mount point]:mount point:' \
						'-d[directory]:directory:' \
						'-z[zfs dataset]:zfs dataset:' \
						'-f[fscomp name]:fscomp name:_pot_fscomps' \
						'-w[zfs remount]' \
						'-r[readonly]'
					;;
				add-dep)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-p[pot name]:pot name:_pot_pots' \
						'-P[dependency pot name]:dependency pot name:_pot_pots'
					;;
				set-rss)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-p[pot name]:pot name:_pot_pots' \
						'-C[Cpuset config]::_normal' \
						'-M[Memory size]::_normal'
					;;
				get-rss)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-p[pot name]:pot name:_pot_pots' \
						'-J[JSON output]'
					;;
				set-cmd)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-p[pot name]:pot name:_pot_pots' \
						'-c[command]::_normal'
					;;
				set-env)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-p[pot name]:pot name:_pot_pots' \
						'*-E[variable list]::_normal'
					;;
				set-hosts)
					_arguments \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-p[pot name]:pot name:_pot_pots' \
						'*-H[hosts entry]::_normal'
					;;
				set-hook)
					_arguments \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-p[pot name]:pot name:_pot_pots' \
						'-s[prestart hook]:prestart hook:_normal' \
						'-S[poststart hook]:poststart hook:_normal' \
						'-t[prestop hook]:prestop hook:_normal' \
						'-T[poststop hook]:poststop hook:_normal'
					;;
				set-attr|set-attribute)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-p[pot name]:pot name:_pot_pots' \
						'-A[attribute]:attribute:_pot_attributes' \
						'-V[value]:value:_normal'
					;;
				get-attr|get-attribute)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-p[pot name]:pot name:_pot_pots' \
						'-A[attribute]:attribute:_pot_attributes' \
						'-q[Quiet output]'
					;;
				export-ports)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-p[pot name]:pot name:_pot_pots' \
						'*-e[port to be exported]::_normal'
					;;
				snap|snapshot)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-r[replace the oldest snapshot]' \
						'-p[pot name]:pot name:_pot_pots' \
						'-f[fscomp name]:fscomp name:_pot_fscomps'
					;;
				revert|rollback)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-p[pot name]:pot name:_pot_pots' \
						'-f[fscomp name]:fscomp name:_pot_fscomps'
					;;
				purge-snapshots)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-p[pot name]:pot name:_pot_pots' \
						'-f[fscomp name]:fscomp name:_pot_fscomps' \
						'-a[all snapshots, instead of the old ones]'
					;;
				update-config)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-p[pot name]:pot name:_pot_pots' \
						'-a[all pots]'
					;;
				export)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-p[pot name]:pot name:_pot_pots' \
						'-t[tag name]::_normal' \
						'-D[target directory]:target directory:_normal' \
						'-l[compression level]:compression level:(0 1 2 3 4 5 6 7 8 9)'
					;;
				import)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-p[pot name]:pot name:' \
						'-t[tag name]::_normal' \
						'-U[URL]:URL:_normal'
					;;
				prepare)
					_arguments -s \
						'-h[Show help]' \
						'-v[Verbose output]' \
						'-S[auto start]' \
						'-p[pot name]:pot name:' \
						'-t[tag name]::_normal' \
						'-a[allocation id]::_normal' \
						'-n[the new pot name]::_normal' \
						'-U[URL]:URL:_normal' \
						'-N[network type]:network type:(inherit alias public-bridge)' \
						'-B[bridge name]:bridge name:_pot_bridges' \
						'-i[network config]::_normal' \
						'*-e[port to be exported]::_normal' \
						'-c[command]::_normal'
					;;
				top)
					_arguments -s \
						'-h[Show help]' \
						'-p[pot name]:pot name:_pot_pots' \
					;;
				stop)
					_arguments '1:pot name:_pot_run_pots'
					;;
				start|term|run)
					_arguments '1:pot name:_pot_pots'
					;;
			esac
			case "$state" in
				pot_names)
					_files -/ -W "${POT_FS_ROOT}/jails/" -S' '
					;;
				fscomp_names)
					_files -/ -W "${POT_FS_ROOT}/fscomp/" -S' '
					;;
				base_names)
					_files -/ -W "${POT_FS_ROOT}/bases/" -S' '
					;;
			esac
	esac
}

_pot_cmds() {
	local -a commands;
	commands=(
	'help:Show help'
	'version:Show version'
	'config:Show framework config values'
	'top:Run top in pot'
	'ls:List elements'
	'list:List elements'
	'show:Show pot resources'
	'info:Show info on pot'
	'top:Show processes (top) running in the pot'
	'ps:Show running pots'
	'init:Init ZFS'
	'de-init:Remove all ZFS datasets'
	'vnet-start:Start the vnet configuration'
	'create-base:Create a new base image'
	'create-fscomp:Create a new fs component'
	'create-private-bridge:Create a new private bridge'
	'create:Create a new pot'
	'clone:Clone a pot'
	'clone-fscomp:Clone a fs component'
	'rename:Rename a pot'
	'destroy:Destroy a pot'
	'prune:Destroy not running prunable pots'
	'copy-in:Copy a file or a directory into a pot'
	'mount-in:Mount a directory, a zfs dataset or a fscomp into a pot'
	'add-dep:Add a dependency to a pot'
	'set-rss:Set a resource constraint to a pot'
	'get-rss:Get the current resource usage'
	'set-cmd:Set the initial command of a pot'
	'set-env:Set environment variables inside a pot'
	'set-hosts:Set etc/hosts entries inside a pot'
	'set-hook:Set hook scripts for a pot'
	'set-attr:Set the value of a pot attribute'
	'set-attribute:Set the value of a pot attribute'
	'get-attr:Get the value of a pot attribute'
	'get-attribute:Get the value of a pot attribute'
	'export-ports:export ports of a pot'
	'start:Start a pot'
	'stop:Stop a pot'
	'run:Start a pot and open a shell in it'
	'term:Open a shell in a pot'
	'snap:Take a snapshot of a pot'
	'snapshot:Take a snapshot of a pot'
	'revert:Restore the last snapshot of a pot'
	'rollback:Restore the last snapshot of a pot'
	'purge-snapshots:Remove old or all snapshots'
	'export:Export a single-type pot'
	'import:Import a single-type pot'
	'prepare:Import and prepare a pot - designed for jail orchestrator'
	'update-config:Update the configuration of a pot'
	)
	_describe 'command' commands
}

_pot
