#compdef easytier-core

autoload -U is-at-least

_easytier-core() {
    typeset -A opt_args
    typeset -a _arguments_options
    local ret=1

    if is-at-least 5.2; then
        _arguments_options=(-s -S -C)
    else
        _arguments_options=(-s -C)
    fi

    local context curcontext="$curcontext" state line
    _arguments "${_arguments_options[@]}" : \
'-w+[config server address, allow format\: full url\: --config-server udp\://127.0.0.1\:22020/admin, '\''udp'\'' can be replaced with tcp, ws, wss (when config server ws is proxied to wss) only user name\: --config-server admin, will use official server ]:CONFIG_SERVER:_default' \
'--config-server=[config server address, allow format\: full url\: --config-server udp\://127.0.0.1\:22020/admin, '\''udp'\'' can be replaced with tcp, ws, wss (when config server ws is proxied to wss) only user name\: --config-server admin, will use official server ]:CONFIG_SERVER:_default' \
'--machine-id=[the machine id to identify this machine, used for config recovery after disconnection, must be unique and fixed. by default it is loaded from persisted local state; on first start it may be migrated from system information or generated, then remains fixed. ]:MACHINE_ID:_default' \
'*-c+[path to the config file, NOTE\: the options set by cmdline args will override options in config file]:CONFIG_FILE:_files' \
'*--config-file=[path to the config file, NOTE\: the options set by cmdline args will override options in config file]:CONFIG_FILE:_files' \
'--config-dir=[Load all .toml files in the directory to start network instances, and store the received configurations in this directory.]:CONFIG_DIR:_files' \
'--network-name=[network name to identify this vpn network]:NETWORK_NAME:_default' \
'--network-secret=[network secret to verify this node belongs to the vpn network]:NETWORK_SECRET:_default' \
'-i+[ipv4 address of this vpn node, if empty, this node will only forward packets and no TUN device will be created]:IPV4:_default' \
'--ipv4=[ipv4 address of this vpn node, if empty, this node will only forward packets and no TUN device will be created]:IPV4:_default' \
'--ipv6=[ipv6 address of this vpn node, can be used together with ipv4 for dual-stack operation]:IPV6:_default' \
'--ipv6-public-addr-provider=[share this node'\''s public IPv6 subnet with other peers so they can obtain public IPv6 addresses (Linux only)]' \
'--ipv6-public-addr-auto=[auto-obtain a public IPv6 address from a peer that shares its IPv6 subnet]' \
'--ipv6-public-addr-prefix=[manually specify the public IPv6 subnet to share, instead of auto-detecting from system routes]:IPV6_PUBLIC_ADDR_PREFIX:_default' \
'-d+[automatically determine and set IP address by Easytier, and the IP address starts from 10.0.0.1 by default. Warning, if there is an IP conflict in the network when using DHCP, the IP will be automatically changed.]' \
'--dhcp=[automatically determine and set IP address by Easytier, and the IP address starts from 10.0.0.1 by default. Warning, if there is an IP conflict in the network when using DHCP, the IP will be automatically changed.]' \
'*-p+[peers to connect initially]' \
'*--peers=[peers to connect initially]' \
'-e+[use a public shared node to discover peers]:EXTERNAL_NODE:_default' \
'--external-node=[use a public shared node to discover peers]:EXTERNAL_NODE:_default' \
'*-n+[export local networks to other peers in the vpn,  e.g.\: 10.0.0.0/24. also support mapping proxy network to other cidr, e.g.\: 10.0.0.0/24->192.168.0.0/24 other peers can access 10.0.0.1 with ip 192.168.0.1 ]:PROXY_NETWORKS:_default' \
'*--proxy-networks=[export local networks to other peers in the vpn,  e.g.\: 10.0.0.0/24. also support mapping proxy network to other cidr, e.g.\: 10.0.0.0/24->192.168.0.0/24 other peers can access 10.0.0.1 with ip 192.168.0.1 ]:PROXY_NETWORKS:_default' \
'*-l+[listeners to accept connections, allow format\: port number\: <11010>. means tcp/udp will listen on 11010, ws/wss will listen on 11010 and 11011, wg will listen on 11011 url\: <tcp\://0.0.0.0\:11010>. tcp can be tcp, udp, ring, wg, ws, wss, quic, faketcp\\n proto & port pair\: <proto\:port>. wg\:11011, means listen on 11011 with wireguard protocol url and proto\:port can occur multiple times. ]' \
'*--listeners=[listeners to accept connections, allow format\: port number\: <11010>. means tcp/udp will listen on 11010, ws/wss will listen on 11010 and 11011, wg will listen on 11011 url\: <tcp\://0.0.0.0\:11010>. tcp can be tcp, udp, ring, wg, ws, wss, quic, faketcp\\n proto & port pair\: <proto\:port>. wg\:11011, means listen on 11011 with wireguard protocol url and proto\:port can occur multiple times. ]' \
'*--mapped-listeners=[manually specify the public address of the listener, other nodes can use this address to connect to this node. e.g.\: tcp\://123.123.123.123\:11223, can specify multiple.]' \
'--hostname=[host name to identify this device]:HOSTNAME:_default' \
'-m+[instance name to identify this vpn node in same machine]:INSTANCE_NAME:_default' \
'--instance-name=[instance name to identify this vpn node in same machine]:INSTANCE_NAME:_default' \
'--vpn-portal=[url that defines the vpn portal, allow other vpn clients to connect. example\: wg\://0.0.0.0\:11010/10.14.14.0/24, means the vpn portal is a wireguard server listening on vpn.example.com\:11010, and the vpn client is in network of 10.14.14.0/24]:VPN_PORTAL:_default' \
'--default-protocol=[default protocol to use when connecting to peers]:DEFAULT_PROTOCOL:_default' \
'-u+[disable encryption for peers communication, default is false, must be same with peers]' \
'--disable-encryption=[disable encryption for peers communication, default is false, must be same with peers]' \
'--encryption-algorithm=[encryption algorithm to use, supported\: '\'''\'', '\''xor'\'', '\''chacha20'\'', '\''aes-gcm'\'', '\''aes-gcm-256'\'', '\''openssl-aes128-gcm'\'', '\''openssl-aes256-gcm'\'', '\''openssl-chacha20'\''. Empty string means default (aes-gcm)]:ENCRYPTION_ALGORITHM:(xor aes-gcm aes-256-gcm chacha20)' \
'--multi-thread=[use multi-thread runtime, default is single-thread]' \
'--multi-thread-count=[the number of threads to use, default is 2, only effective when multi-thread is enabled, must be greater than 2]:MULTI_THREAD_COUNT:_default' \
'--disable-ipv6=[do not use ipv6]' \
'--dev-name=[optional tun interface name]:DEV_NAME:_default' \
'--mtu=[mtu of the TUN device, default is 1380 for non-encryption, 1360 for encryption]:MTU:_default' \
'--latency-first=[latency first mode, will try to relay traffic with lowest latency path, default is using shortest path]' \
'*--exit-nodes=[exit nodes to forward all traffic to, a virtual ipv4 address, priority is determined by the order of the list]' \
'--enable-exit-node=[allow this node to be an exit node]' \
'--proxy-forward-by-system=[forward packet to proxy networks via system kernel, disable internal nat for network proxy]' \
'--no-tun=[do not create TUN device, can use subnet proxy to access node]' \
'--use-smoltcp=[enable smoltcp stack for subnet proxy and kcp proxy]' \
'*--manual-routes=[assign routes cidr manually, will disable subnet proxy and wireguard routes propagated from peers. e.g.\: 192.168.0.0/16]' \
'*--relay-network-whitelist=[only forward traffic from the whitelist networks, supporting wildcard strings, multiple network names can be separated by spaces. if local network (assigned with network_name) is not in the whitelist, the traffic can still be forwarded if no other route path is available. if this parameter is empty, forwarding is disabled. by default, all networks are allowed. e.g.\: '\''*'\'' (all networks), '\''def*'\'' (networks with the prefix '\''def'\''), '\''net1 net2'\'' (only allow net1 and net2)" ]' \
'--p2p-only=[only communicate with peers that already establish p2p connection]' \
'--lazy-p2p=[only try to establish p2p when traffic actually needs the peer; peers marked as need-p2p are still connected proactively]' \
'--disable-p2p=[disable ordinary automatic p2p; still establish p2p with peers marked as need-p2p, and other peers should not proactively connect to this node]' \
'--disable-udp-hole-punching=[disable udp hole punching]' \
'--disable-tcp-hole-punching=[disable tcp hole punching]' \
'--disable-sym-hole-punching=[if true, disable udp nat hole punching for symmetric nat (NAT4), which is based on birthday attack and may be blocked by ISP.]' \
'--disable-upnp=[disable runtime UPnP/NAT-PMP port mapping for eligible listeners; automatic port mapping is enabled by default]' \
'--enable-udp-broadcast-relay=[Windows only\: capture local UDP broadcast packets from physical interfaces and forward them to EasyTier peers. Helps games to find rooms in local network. Requires administrator privileges.]' \
'--relay-all-peer-rpc=[relay all peer rpc packets, even if the peer is not in the relay network whitelist. this can help peers not in relay network whitelist to establish p2p connection.]' \
'--need-p2p=[announce that other peers should proactively establish p2p connections to this node even when they enable lazy-p2p]' \
'--socks5=[enable socks5 server, allow socks5 client to access virtual network. format\: <port>, e.g.\: 1080]:SOCKS5:_default' \
'--compression=[compression algorithm to use, support none, zstd. default is none]:COMPRESSION:_default' \
'--bind-device=[bind the connector socket to physical devices to avoid routing issues. e.g.\: subnet proxy segment conflicts with a node'\''s segment, after binding the physical device, it can communicate with the node normally.]:BIND_DEVICE:(true false)' \
'--enable-kcp-proxy=[proxy tcp streams with kcp, improving the latency and throughput on the network with udp packet loss.]' \
'--disable-kcp-input=[do not allow other nodes to use kcp to proxy tcp streams to this node. when a node with kcp proxy enabled accesses this node, the original tcp connection is preserved.]' \
'--enable-quic-proxy=[proxy tcp streams with QUIC, improving the latency and throughput on the network with udp packet loss.]' \
'--disable-quic-input=[do not allow other nodes to use QUIC to proxy tcp streams to this node. when a node with QUIC proxy enabled accesses this node, the original tcp connection is preserved.]' \
'*--port-forward=[forward local port to remote port in virtual network. e.g.\: udp\://0.0.0.0\:12345/10.126.126.1\:23456, means forward local udp port 12345 to 10.126.126.1\:23456 in the virtual network. can specify multiple.]:PORT_FORWARD:_default' \
'--accept-dns=[if true, enable magic dns. with magic dns, you can access other nodes with a domain name, e.g.\: <hostname>.et.net. magic dns will modify your system dns settings, enable it carefully.]:ACCEPT_DNS:(true false)' \
'--tld-dns-zone=[specify the top-level domain zone for magic DNS. if not provided, defaults to the value from dns_server module (et.net.). only used when accept_dns is true.]:TLD_DNS_ZONE:_default' \
'--private-mode=[if true, foreign networks are only allowed when this node can verify they use the same network secret, or when a foreign credential node is already trusted via admin-issued credential propagation; different or missing secrets are otherwise rejected.]:PRIVATE_MODE:(true false)' \
'--foreign-relay-bps-limit=[the maximum bps limit for foreign network relay, default is no limit. unit\: BPS (bytes per second)]:FOREIGN_RELAY_BPS_LIMIT:_default' \
'--instance-recv-bps-limit=[the maximum total receive bps limit for this instance, default is no limit. unit\: BPS (bytes per second)]:INSTANCE_RECV_BPS_LIMIT:_default' \
'*--tcp-whitelist=[tcp port whitelist. Supports single ports (80) and ranges (8000-9000)]' \
'*--udp-whitelist=[udp port whitelist. Supports single ports (53) and ranges (5000-6000)]' \
'--disable-relay-kcp=[if true, disable relay kcp packets. avoid consuming too many bandwidth. default is false]' \
'--disable-relay-quic=[if true, disable relay quic packets. avoid consuming too many bandwidth. default is false]' \
'--enable-relay-foreign-network-kcp=[if true, allow relay kcp packets from foreign network. default is false (not forward foreign network kcp packets)]' \
'--enable-relay-foreign-network-quic=[if true, allow relay quic packets from foreign network. default is false (not forward foreign network quic packets)]' \
'*--stun-servers=[Override default STUN servers; If configured but empty, STUN servers are not used]' \
'*--stun-servers-v6=[Override default STUN servers, IPv6; If configured but empty, IPv6 STUN servers are not used]' \
'--secure-mode=[if true, enable secure mode. default is false]' \
'--local-private-key=[local private key for secure mode. if not provided, a random key will be generated]:LOCAL_PRIVATE_KEY:_default' \
'--local-public-key=[local public key for secure mode. if not provided, a random key will be generated, or use local private key to derive public key]:LOCAL_PUBLIC_KEY:_default' \
'--credential=[credential secret (base64-encoded private key) for joining network as a temporary node without network_secret]:CREDENTIAL:_default' \
'--credential-file=[path to credential storage file for persisting generated credentials across restarts (admin nodes)]:CREDENTIAL_FILE:_files' \
'--console-log-level=[console log level]:CONSOLE_LOG_LEVEL:_default' \
'--file-log-level=[file log level]:FILE_LOG_LEVEL:_default' \
'--file-log-dir=[directory to store log files]:FILE_LOG_DIR:_default' \
'--file-log-size=[per file log size in MB, default is 100MB]:FILE_LOG_SIZE:_default' \
'--file-log-count=[max file log count, default is 10]:FILE_LOG_COUNT:_default' \
'-r+[rpc portal address to listen for management. 0 means random port, 12345 means listen on 12345 of localhost, 0.0.0.0\:12345 means listen on 12345 of all interfaces. default is 0 and will try 15888 first]:RPC_PORTAL:_default' \
'--rpc-portal=[rpc portal address to listen for management. 0 means random port, 12345 means listen on 12345 of localhost, 0.0.0.0\:12345 means listen on 12345 of all interfaces. default is 0 and will try 15888 first]:RPC_PORTAL:_default' \
'*--rpc-portal-whitelist=[rpc portal whitelist, only allow these addresses to access rpc portal, e.g.\: 127.0.0.1,127.0.0.0/8,\:\:1/128]:RPC_PORTAL_WHITELIST:_default' \
'--gen-autocomplete=[generate shell completions]:GEN_AUTOCOMPLETE:(bash elvish fish powershell zsh nu)' \
'--no-listener[do not listen on any port, only connect to peers]' \
'--check-config[Check config validity without starting the network]' \
'--daemon[Run in daemon mode]' \
'--disable-env-parsing[disable environment variable parsing in config file]' \
'-h[Print help]' \
'--help[Print help]' \
'-V[Print version]' \
'--version[Print version]' \
&& ret=0
}

(( $+functions[_easytier-core_commands] )) ||
_easytier-core_commands() {
    local commands; commands=()
    _describe -t commands 'easytier-core commands' commands "$@"
}

if [ "$funcstack[1]" = "_easytier-core" ]; then
    _easytier-core "$@"
else
    compdef _easytier-core easytier-core
fi
