#compdef pfctl

local pfctl_flush_modifiers pfctl_optimizer_level pfctl_show_modifiers pfctl_tables_command pfctl_debug_level

pfctl_flush_modifiers=(
    'all:flush all'
    'info:flush the filter information'
    'nat:flush the NAT rules'
    'osfp:flush the passive operating system fingerprints'
    'queue:flush the queue rules'
    'rules:flush the filter rules'
    'state:flush the stable table'
    'Sources:flush the source tracking table'
    'Tables:flush the tables'
)

pfctl_show_modifiers=(
    'nat:show the currently loaded NAT rules'
    'queue:show the currently loaded queue rules'
    'rules:show the currently loaded filter rules'
    'Anchors:show the currently loaded anchors directly attached to the main ruleset'
    'state:show the contents of the state table'
    'Sources:show the contents of the source tracking table'
    'info:show filter information'
    'labels:show per-rule statistics of filter rules with labels'
    'timeouts:show the current global timeouts'
    'memory:show the current pool memory hard limits'
    'Tables:show the list of tables'
    'osfp:show the list of operating system fingerprints'
    'Interfaces:show the list of interfaces and interface drivers available to PF'
    'all:show all except for the lists of interfaces and operating system fingerprints'
)

pfctl_optimizer_level=(
    'none:disable the ruleset optimizer'
    'basic:enable basic ruleset optimizations'
    'profile:enable basic ruleset optimizations with profiling'
)
pfctl_tables_command=(
    'kill:kill a table'
    'flush:flush all addresses of a table'
    'add:add one or more addresses in a table'
    'delete:delete one or more addresses from a table'
    'expire:delete addresses which had their statistics cleared more than number seconds ago'
    'replace:replace the addresses of the table'
    'show:show the content (addresses) of a table'
    'test:test if the given addresses match a table'
    'zero:clear all the statistics of a table'
    'load:load only the table definitions from pf.conf(5)'
)
pfctl_debug_level=(
    "none:don\'t generate debug messages" 
    'urgent:generate debug messages only for serious errors' 
    'misc:generate debug messages for various errors' 
    'loud:generate debug messages for common conditions'
)
_iface() {
    local pfctl_iface
    pfctl_iface=($(pfctl -s Interfaces))
    compadd $pfctl_iface
}
_tables() {
    local pfctl_tables
    pfctl_tables=($(pfctl -s Tables))
     compadd $pfctl_tables
}
# TODO:
# Missing -a
#
_arguments -s \
    '-F[flush the filter parameters specified by modifier]:modifier:(($pfctl_flush_modifiers))' \
    '-A[load only the queue rules present in the rule file]' \
    '-D[define macro to be set to value]:macro:' \
    '-d[disable the packet filter]' \
    '-e[enable the packet filter]' \
    '-f[load the rules contained in a file]:configuration file:_files' \
    '-g[include output helpful for debugging]' \
    '-h[help]' \
    '-i[restrict the operation to the given interface]:interface:_iface' \
    '-K[kill all of the source tracking entries originating from the specified host or network]:host or network:_hosts' \
    '-k[kill all of the state entries originating from the specified host or network]:host or network:_hosts' \
    '-m[merge in explicitly given options]' \
    '-N[load only the NAT rules present in the rule file]' \
    '-n[do not actually load rules, just parse them]' \
    '-O[load only the options present in the rule file]' \
    '-o[control the ruleset optimizer]:level:(($pfctl_optimizer_level))' \
    '-p[use the device file device instead of the default /dev/pf]:device:_files' \
    '-q[only print errors and warnings]' \
    '-R[load only the filter rules present in the rule file]' \
    '-r[perform reverse DNS lookups on states when displaying them]' \
    '-s[show the filter parameters specified by modifier]:modifier:(($pfctl_show_modifiers ))' \
    '-T[specify the command to apply to the table]:command:(($pfctl_tables_command))' \
    '-t[specify the name of the table]:table:_tables' \
    '-v[produce more verbose output]' \
    '-x[set the debug level]:debug level:(($pfctl_debug_level))' \
    '-z[clear per-rule statistics]'
