#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]'
