<?xml version="1.0" encoding="UTF-8"?>
<KLISH
  xmlns="https://klish.libcode.org/klish3"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="https://src.libcode.org/pkun/klish/src/master/klish.xsd">

<PLUGIN name="klish"/>
<PLUGIN name="infix"/>
<PLUGIN name="script"/>
<PLUGIN name="sysrepo">
  ShowBrackets = y
  ShowSemicolons = y
  KeysWithStatement = y
  FirstKeyWithStatement = n
  Colorize = y
  Indent = 2
  DefaultKeys = y
  ShowDefaultKeys = y
  HidePasswords = n
  EnableNACM = y
  Oneliners = n
</PLUGIN>

<PTYPE name="CFG">
  <COMPL>
    <ACTION sym="datastore@infix">cfg</ACTION>
  </COMPL>
  <ACTION sym="STRING"/>
</PTYPE>

<PTYPE name="DATASTORE">
  <COMPL>
    <ACTION sym="datastore@infix">src</ACTION>
  </COMPL>
  <ACTION sym="STRING"/>
</PTYPE>

<PTYPE name="RW_DATASTORE">
  <COMPL>
    <ACTION sym="datastore@infix">dst</ACTION>
  </COMPL>
  <ACTION sym="STRING"/>
</PTYPE>

<PTYPE name="PLINE_SET">
  <COMPL>
    <ACTION sym="srp_compl@sysrepo"/>
  </COMPL>
  <HELP>
    <ACTION sym="srp_help@sysrepo"/>
  </HELP>
  <ACTION sym="PLINE_SET@sysrepo"/>
</PTYPE>

<PTYPE name="PLINE_DEL">
  <COMPL>
    <ACTION sym="srp_compl@sysrepo"/>
  </COMPL>
  <HELP>
    <ACTION sym="srp_help@sysrepo"/>
  </HELP>
  <ACTION sym="PLINE_DEL@sysrepo"/>
</PTYPE>

<PTYPE name="PLINE_EDIT">
  <COMPL>
    <ACTION sym="srp_compl@sysrepo"/>
  </COMPL>
  <HELP>
    <ACTION sym="srp_help@sysrepo"/>
  </HELP>
  <ACTION sym="PLINE_EDIT@sysrepo"/>
</PTYPE>

<PTYPE name="PLINE_INSERT_FROM">
  <COMPL>
    <ACTION sym="srp_compl@sysrepo"/>
  </COMPL>
  <HELP>
    <ACTION sym="srp_help@sysrepo"/>
  </HELP>
  <ACTION sym="PLINE_INSERT_FROM@sysrepo"/>
</PTYPE>

<PTYPE name="PLINE_INSERT_TO">
  <COMPL>
    <ACTION sym="srp_compl_insert_to@sysrepo"/>
  </COMPL>
  <HELP>
    <ACTION sym="srp_help_insert_to@sysrepo"/>
  </HELP>
  <ACTION sym="PLINE_INSERT_TO@sysrepo"/>
</PTYPE>

<PTYPE name="LOGFILES">
  <COMPL>
    <ACTION sym="files@infix">/var/log</ACTION>
  </COMPL>
  <ACTION sym="STRING"/>
</PTYPE>

<PTYPE name="FILES">
  <COMPL>
    <ACTION sym="files@infix">/cfg</ACTION>
  </COMPL>
  <ACTION sym="STRING"/>
</PTYPE>

<PTYPE name="IFACES">
  <COMPL>
    <ACTION sym="ifaces@infix"/>
  </COMPL>
  <ACTION sym="STRING"/>
</PTYPE>

<PTYPE name="FIREWALL_ZONES">
  <COMPL>
    <ACTION sym="firewall_zones@infix"/>
  </COMPL>
  <ACTION sym="STRING"/>
</PTYPE>

<PTYPE name="FIREWALL_POLICIES">
  <COMPL>
    <ACTION sym="firewall_policies@infix"/>
  </COMPL>
  <ACTION sym="STRING"/>
</PTYPE>

<PTYPE name="FIREWALL_SERVICES">
  <COMPL>
    <ACTION sym="firewall_services@infix"/>
  </COMPL>
  <ACTION sym="STRING"/>
</PTYPE>

<PTYPE name="BOOT_TARGET">
  <COMPL>
    <ACTION sym="boot_targets@infix"/>
  </COMPL>
  <ACTION sym="STRING"/>
</PTYPE>

<PTYPE name="USERS">
  <COMPL>
    <ACTION sym="users@infix"/>
  </COMPL>
  <ACTION sym="STRING"/>
</PTYPE>

<PTYPE name="GROUPS">
  <COMPL>
    <ACTION sym="groups@infix"/>
  </COMPL>
  <ACTION sym="STRING"/>
</PTYPE>

<PTYPE name="SYM_KEYS">
  <COMPL>
    <ACTION sym="sym_keys@infix"/>
  </COMPL>
  <ACTION sym="STRING"/>
</PTYPE>

<PTYPE name="ASYM_KEYS">
  <COMPL>
    <ACTION sym="asym_keys@infix"/>
  </COMPL>
  <ACTION sym="STRING"/>
</PTYPE>

<VIEW name="main">
  <HOTKEY key="^D" cmd="exit"/>

  <PROMPT>
    <ACTION sym="prompt" exec_on="always">%u@%h:/> </ACTION>
</PROMPT>

<COMMAND name="help" help="Help system (try also the '?' key)">
  <PARAM name="topic" ptype="/STRING" min="0" help="Help topic">
    <COMPL>
      <ACTION sym="printl">configure</ACTION>
      <ACTION sym="printl">introduction</ACTION>
      <ACTION sym="printl">keybindings</ACTION>
      <ACTION sym="printl">netcalc</ACTION>
      <ACTION sym="printl">quick</ACTION>
      <ACTION sym="printl">tcpdump</ACTION>
      <ACTION sym="printl">text-editor</ACTION>
      <ACTION sym="printl">upgrade</ACTION>
    </COMPL>
  </PARAM>
  <ACTION sym="script" in="tty" out="tty" interrupt="true">
    topic=${KLISH_PARAM_topic:-quick}
    fn="/usr/share/infix/cli/${topic}.md"
    if [ -f "$fn" ]; then
      lowdown -t term --term-vmargin=1 "$fn" |pager
    else
      echo "Help topic not available, try help without an argument, or tap '?' for a list."
    fi
  </ACTION>
</COMMAND>

<COMMAND name="poweroff" help="Poweroff system (system policy may yield reboot)">
  <ACTION sym="srp_rpc@sysrepo" ptype="STRING">/ietf-system:system-shutdown</ACTION>
</COMMAND>

<COMMAND name="reboot" help="Reboot system">
  <ACTION sym="srp_rpc@sysrepo" ptype="STRING">/ietf-system:system-restart</ACTION>
</COMMAND>

<COMMAND name="exit" help="Exit from CLI (log out)">
  <ACTION sym="nav">pop</ACTION>
</COMMAND>
<COMMAND name="logout" help="Alias to exit">
  <ACTION sym="nav">pop</ACTION>
</COMMAND>

<COMMAND name="configure" help="Create new candidate-config based on running-config">
  <ACTION sym="nav">replace config</ACTION>
</COMMAND>

<COMMAND name="copy" help="Copy file or configuration, e.g., copy running-config startup-config">
  <PARAM name="src" ptype="/DATASTORE"    help="Source datastore or file, e.g., tftp://ip/file"/>
  <PARAM name="dst" ptype="/RW_DATASTORE" help="Destination datastore or file, e.g., scp://ip/file"/>
  <SWITCH name="optional" min="0">
    <COMMAND name="validate"              help="Validate configuration without applying"/>
    <PARAM name="user" ptype="/STRING"    help="Remote username (interactive password)"/>
  </SWITCH>
  <ACTION sym="copy@infix" in="tty" out="tty" interrupt="true"/>
</COMMAND>

<COMMAND name="dir" help="List available files">
  <SWITCH name="optional" min="0">
    <PARAM name="path" ptype="/STRING" help="Directory contents to list"/>
  </SWITCH>
  <ACTION sym="script" in="tty" out="tty" interrupt="true">
    dir $KLISH_PARAM_path
  </ACTION>
</COMMAND>

<COMMAND name="remove" help="Remove a configuration file">
  <PARAM name="file" ptype="/FILES" help="Configuration file"/>
  <ACTION sym="erase@infix" in="tty" out="tty" interrupt="true"/>
</COMMAND>

<COMMAND name="password" help="Password tools" mode="switch">
  <COMMAND name="generate" help="Generate random passwords using pwgen">
    <ACTION sym="script">pwgen -C -s 13 20</ACTION>
  </COMMAND>

  <COMMAND name="encrypt" help="Encrypt a password string">
    <SWITCH name="optional" min="0" max="4">
      <COMMAND name="salt" help="Random data to salt with before hashing.">
        <PARAM name="pwsalt" ptype="/STRING" help="Must not use prefix like $1$"/>
      </COMMAND>
      <COMMAND name="type" help="Optional hash algorithm type.">
        <PARAM name="pwhash" ptype="/STRING" help="Hash crypt algorithm.">
          <COMPL>
            <ACTION sym="printl">md5crypt</ACTION>
            <ACTION sym="printl">sha256crypt</ACTION>
            <ACTION sym="printl">sha512crypt</ACTION>
            <ACTION sym="printl">yescrypt</ACTION>
          </COMPL>
        </PARAM>
      </COMMAND>
      <PARAM name="pwpass" ptype="/STRING" help="Optional clear text password (no spaces)"/>
    </SWITCH>
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      type=${KLISH_PARAM_pwhash:-yescrypt}
      salt=${KLISH_PARAM_pwsalt:+-S $KLISH_PARAM_pwsalt}
      mkpasswd -m $type $salt $KLISH_PARAM_pwpass
    </ACTION>
  </COMMAND>
</COMMAND>

<COMMAND name="wireguard" help="WireGuard VPN key tools" mode="switch">
  <COMMAND name="genkey" help="Generate a WireGuard private/public key pair">
    <ACTION sym="script">
priv=$(wg genkey)
pub=$(printf '%s' "$priv" | wg pubkey)
echo "Private: $priv"
echo "Public:  $pub"
    </ACTION>
  </COMMAND>

  <COMMAND name="genpsk" help="Generate a WireGuard pre-shared key">
    <ACTION sym="script">wg genpsk</ACTION>
  </COMMAND>
</COMMAND>

<COMMAND name="set" help="Set operations, e.g., current date/time" mode="switch">
  <COMMAND name="datetime" help="Set current date and time, ISO-8601 format">
    <PARAM name="current-datetime" ptype="/STRING" help="yyyy-mm-ddThh:mm:ss(Z|+/-hh:mm)"/>
    <ACTION sym="srp_rpc@sysrepo">/ietf-system:set-current-datetime</ACTION>
  </COMMAND>

  <COMMAND name="boot-order" help="Set boot partition order">
    <PARAM name="first" ptype="/BOOT_TARGET" help="First boot target"/>
    <PARAM name="second" ptype="/BOOT_TARGET" help="Second boot target" min="0"/>
    <PARAM name="third" ptype="/BOOT_TARGET" help="Third boot target" min="0"/>
    <ACTION sym="set_boot_order@infix"/>
  </COMMAND>
</COMMAND>

<COMMAND name="dhcp-server" help="DHCP server tools" mode="switch">
  <COMMAND name="clear-statistics" help="Clear DHCP server statistics">
    <ACTION sym="srp_rpc@sysrepo">/infix-dhcp-server:dhcp-server/statistics/clear</ACTION>
  </COMMAND>
</COMMAND>

<COMMAND name="show" help="Show system status and configuration files" mode="switch">

  <COMMAND name="bridge" help="Show bridge (ports/fdb/mdb/vlans)">
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      bridge -color link |pager
    </ACTION>

    <SWITCH name="optional" min="0">
      <COMMAND name="fdb" help="Show unicast forwarding database">
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          bridge -color fdb |pager
        </ACTION>
      </COMMAND>
      <COMMAND name="mdb" help="Show mulficast forwarding database">
        <SWITCH name="optional" min="0">
          <COMMAND name="detailed" help="Detailed (full) output">
            <ACTION sym="script" in="tty" out="tty" interrupt="true">
              bridge -color -d mdb |pager
            </ACTION>
          </COMMAND>
        </SWITCH>
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          show --raw interface | /usr/libexec/statd/cli-pretty show-bridge-mdb |pager
        </ACTION>
      </COMMAND>
      <COMMAND name="stp" help="Show spanning tree status">
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          show --raw interface | /usr/libexec/statd/cli-pretty show-bridge-stp |pager
        </ACTION>
      </COMMAND>
      <COMMAND name="vlan" help="Show VLAN table">
        <ACTION sym="script">bridge -color vlan</ACTION>
        <SWITCH name="optional" min="0">
          <COMMAND name="detailed" help="Detailed (full) output">
            <ACTION sym="script" in="tty" out="tty" interrupt="true">
              bridge -color -d vlan |pager
            </ACTION>
          </COMMAND>
        </SWITCH>
      </COMMAND>
    </SWITCH>
  </COMMAND>

  <COMMAND name="datetime" help="Show current date and time, default RFC2822 format">
    <ACTION sym="script">date -R</ACTION>
    <SWITCH name="optional" min="0">
      <COMMAND name="iso" min="0" help="NETCONF/ISO-8601 format">
        <ACTION sym="script">date -Isec</ACTION>
      </COMMAND>
    </SWITCH>
  </COMMAND>

  <COMMAND name="dns" help="Show DNS (client) status">
    <!-- Show static/configured nameservers and then all learned ones from DHCP clients -->
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      cat /etc/resolv.conf.head 2>/dev/null; resolvconf -l | sed 's/#.*//; /^\s*$/d' |pager
    </ACTION>
  </COMMAND>

  <COMMAND name="keystore" help="Show keystore keys">
    <SWITCH name="subcommands" min="0">
      <COMMAND name="symmetric" help="Show details for a symmetric key">
	<PARAM name="name" ptype="/SYM_KEYS" help="Key name"/>
        <ACTION sym="script" in="tty" out="tty" interrupt="true">show keystore symmetric $KLISH_PARAM_name</ACTION>
      </COMMAND>
      <COMMAND name="asymmetric" help="Show details for an asymmetric key">
	<PARAM name="name" ptype="/ASYM_KEYS" help="Key name"/>
        <ACTION sym="script" in="tty" out="tty" interrupt="true">show keystore asymmetric $KLISH_PARAM_name</ACTION>
      </COMMAND>
    </SWITCH>
    <ACTION sym="script" in="tty" out="tty" interrupt="true">show keystore</ACTION>
  </COMMAND>

  <COMMAND name="nacm" help="Show users and NACM status and groups">
    <SWITCH name="subcommands" min="0">
      <COMMAND name="group" help="Show details for a specific NACM group">
	<PARAM name="name" ptype="/GROUPS" help="Group name"/>
        <ACTION sym="script" in="tty" out="tty" interrupt="true">show nacm group $KLISH_PARAM_name</ACTION>
      </COMMAND>
      <COMMAND name="user" help="Show NACM details for a specific user">
	<PARAM name="name" ptype="/USERS" help="User name"/>
        <ACTION sym="script" in="tty" out="tty" interrupt="true">show nacm user $KLISH_PARAM_name</ACTION>
      </COMMAND>
    </SWITCH>
    <ACTION sym="script" in="tty" out="tty" interrupt="true">show nacm</ACTION>
  </COMMAND>

  <COMMAND name="ntp" help="Show NTP status">
    <SWITCH name="subcommands" min="0">
      <COMMAND name="source" help="Show NTP source(s)">
	<SWITCH name="optional" min="0" max="1">
	  <PARAM name="address" ptype="/STRING" help="Show details for specific source address"/>
	</SWITCH>
        <ACTION sym="script">show ntp source $KLISH_PARAM_address</ACTION>
      </COMMAND>
      <COMMAND name="tracking" help="Show NTP tracking">
        <ACTION sym="script">show ntp tracking</ACTION>
      </COMMAND>
    </SWITCH>
    <ACTION sym="script">show ntp</ACTION>
  </COMMAND>

  <COMMAND name="dhcp-server" help="Show DHCP server status">
    <ACTION sym="script" in="tty" out="tty" interrupt="true">show dhcp</ACTION>

    <SWITCH name="optional" min="0">
      <COMMAND name="statistics" help="Show DHCP server statistics">
        <ACTION sym="script" in="tty" out="tty" interrupt="true">show dhcp stat</ACTION>
      </COMMAND>

      <COMMAND name="detailed" help="Detailed (full operational) output">
        <ACTION sym="script" in="tty" out="tty" interrupt="true">show dhcp detail</ACTION>
      </COMMAND>

    </SWITCH>
  </COMMAND>

  <COMMAND name="services" help="Show system services">
    <ACTION sym="script">
      show services
    </ACTION>
  </COMMAND>

  <COMMAND name="software" help="Show software info">
    <SWITCH name="optional" min="0" max="1">
      <COMMAND name="name" help="Show detailed info about a partition">
        <PARAM name="name" ptype="/STRING" help="Partition name" />
      </COMMAND>
    </SWITCH>
    <ACTION sym="script">
      show software "$KLISH_PARAM_name"
    </ACTION>
  </COMMAND>

  <COMMAND name="boot-order" help="Show boot partition order">
    <ACTION sym="script">
      show boot-order
    </ACTION>
  </COMMAND>

  <COMMAND name="system" help="Show system overview">
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      show system |pager
    </ACTION>
  </COMMAND>

  <COMMAND name="bfd" help="Show BFD information">
    <PARAM name="subcommand" ptype="/STRING" help="peers or peer" min="0" max="1">
      <COMPL>
        <ACTION sym="printl">peers</ACTION>
        <ACTION sym="printl">peer</ACTION>
      </COMPL>
    </PARAM>
    <PARAM name="peer" ptype="/STRING" help="Peer IP address" min="0" max="1"/>
    <SWITCH name="optional" min="0">
      <COMMAND name="brief" help="Show brief output" mode="switch"/>
    </SWITCH>
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      BRIEF_ARG=""
      if [ -n "$KLISH_COMMAND_brief" ]; then
        BRIEF_ARG="brief"
      fi
      # Pass subcommand, optional peer address, and brief flag
      show bfd ${KLISH_PARAM_subcommand:+"$KLISH_PARAM_subcommand"} ${KLISH_PARAM_peer:+"$KLISH_PARAM_peer"} ${BRIEF_ARG:+"$BRIEF_ARG"} |pager
    </ACTION>
  </COMMAND>

  <COMMAND name="ospf" help="Show OSPF status">
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      show ospf |pager
      # Deprecated in favor of Cisco likeness, consider future 'show ipv6 ospf'
      printf "\n\e[1mNOTE:\e[0m this command is deprecated, please use 'show ip ospf' instead.\n"
    </ACTION>

    <SWITCH name="optional" min="0">
      <COMMAND name="neighbor" help="Show OSPF neighbors">
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          show ospf neighbor |pager
          printf "\n\e[1mNOTE:\e[0m this command is deprecated, please use 'show ip ospf neighbor' instead.\n"
        </ACTION>
      </COMMAND>

      <COMMAND name="interface" help="Show OSPF interfaces">
        <SWITCH name="optional" min="0" max="1">
          <PARAM name="ifname" ptype="/IFACES" help="Interface name" />
        </SWITCH>
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          show ospf interface "$KLISH_PARAM_ifname" |pager
          printf "\n\e[1mNOTE:\e[0m this command is deprecated, please use 'show ip ospf interface' instead.\n"
        </ACTION>
      </COMMAND>

      <COMMAND name="route" help="Show OSPF routing table">
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          show ospf route |pager
          printf "\n\e[1mNOTE:\e[0m this command is deprecated, please use 'show ip ospf route' instead.\n"
        </ACTION>
      </COMMAND>
    </SWITCH>
  </COMMAND>

  <COMMAND name="route" help="Show routing table">
    <PARAM name="ip" ptype="/STRING" help="ipv4 or ipv6" min="0" max="1">
      <COMPL>
        <ACTION sym="printl">ipv4</ACTION>
        <ACTION sym="printl">ipv6</ACTION>
      </COMPL>
    </PARAM>
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      show routes $KLISH_PARAM_ip route |pager
      # Deprecated in favor of Cisco likeness
      printf "\n\e[1mNOTE:\e[0m this command is deprecated, please use 'show ip route' instead.\n"
    </ACTION>
  </COMMAND>

  <COMMAND name="lldp" help="Show LLDP neighbors">
    <ACTION sym="script">
      show lldp
    </ACTION>
  </COMMAND>

  <COMMAND name="hardware" help="Show hardware information">
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      show hardware |pager
    </ACTION>
  </COMMAND>

  <!-- https://www.cisco.com/c/en/us/td/docs/wireless/access_point/mob_exp/83/cmd-ref/me_cr_book/me_ports_and_interfaces_cli.html -->
  <COMMAND name="interface" help="Show interface info, default an overview of all">
    <SWITCH name="optional" min="0" max="1">
      <PARAM name="ifname" ptype="/IFACES" help="Interface name" />
    </SWITCH>
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      show interface "$KLISH_PARAM_ifname" |pager
    </ACTION>
  </COMMAND>

  <COMMAND name="ip" help="Show IP level status (Layer-3)">
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      ip -color addr |pager
    </ACTION>

    <SWITCH name="optional" min="0">
      <COMMAND name="brief" help="Simplified (human-readable) output" mode="switch">
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          ip -color -br addr | sort -V | sed 's/@dsa[0-9]/     /' |pager
        </ACTION>
      </COMMAND>

      <COMMAND name="detailed" help="Detailed (full) output" mode="switch">
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          ip -color -d addr |pager
        </ACTION>
      </COMMAND>

      <COMMAND name="multicast" help="Show IGMP/MLD status" mode="switch">
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          mctl |pager
        </ACTION>
      </COMMAND>

      <COMMAND name="route" help="Show routing table">
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
	  show routes ipv4 |pager
        </ACTION>
      </COMMAND>

      <COMMAND name="ospf" help="Show OSPF status">
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          show ospf |pager
        </ACTION>

        <SWITCH name="optional" min="0">
          <COMMAND name="neighbor" help="Show OSPF neighbors">
            <ACTION sym="script" in="tty" out="tty" interrupt="true">
              show ospf neighbor |pager
            </ACTION>
          </COMMAND>

          <COMMAND name="interface" help="Show OSPF interfaces">
            <SWITCH name="optional" min="0" max="1">
              <PARAM name="ifname" ptype="/IFACES" help="Interface name" />
            </SWITCH>
            <ACTION sym="script" in="tty" out="tty" interrupt="true">
              show ospf interface "$KLISH_PARAM_ifname" |pager
            </ACTION>
          </COMMAND>

          <COMMAND name="route" help="Show OSPF routing table">
            <ACTION sym="script" in="tty" out="tty" interrupt="true">
              show ospf route |pager
            </ACTION>
          </COMMAND>
        </SWITCH>
      </COMMAND>

      <COMMAND name="rip" help="Show RIP status">
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          show rip |pager
        </ACTION>

        <SWITCH name="optional" min="0">
          <COMMAND name="route" help="Show RIP routing table">
            <ACTION sym="script" in="tty" out="tty" interrupt="true">
              show rip route |pager
            </ACTION>
          </COMMAND>

          <COMMAND name="interface" help="Show RIP interfaces">
            <SWITCH name="optional" min="0" max="1">
              <PARAM name="ifname" ptype="/IFACES" help="Interface name" />
            </SWITCH>
            <ACTION sym="script" in="tty" out="tty" interrupt="true">
              show rip interface "$KLISH_PARAM_ifname" |pager
            </ACTION>
          </COMMAND>

          <COMMAND name="neighbor" help="Show RIP neighbors">
            <ACTION sym="script" in="tty" out="tty" interrupt="true">
              show rip neighbor |pager
            </ACTION>
          </COMMAND>
        </SWITCH>
      </COMMAND>
    </SWITCH>
  </COMMAND>

  <COMMAND name="ipv6" help="Show IPv6 level status (Layer-3)">
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      ip -color -6 addr |pager
    </ACTION>

    <SWITCH name="optional" min="0">
      <COMMAND name="brief" help="Simplified (human-readable) output" mode="switch">
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          ip -color -6 -br addr | sort -V | sed 's/@dsa[0-9]/     /' |pager
        </ACTION>
      </COMMAND>

      <COMMAND name="detailed" help="Detailed (full) output" mode="switch">
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          ip -color -6 -d addr |pager
        </ACTION>
      </COMMAND>

      <COMMAND name="route" help="Show IPv6 routing table" mode="switch">
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          show routes ipv6 |pager
        </ACTION>
      </COMMAND>
    </SWITCH>
  </COMMAND>

  <COMMAND name="log" help="Show log file (jumps to end), default: syslog">
    <PARAM name="fn" ptype="/LOGFILES" min="0" help="Optional log file to show"/>
    <SWITCH name="optional" min="0">
      <COMMAND name="tail" help="Show log tail, last N lines only">
        <PARAM name="lines" ptype="/UINT" help="Last number of lines to show"/>
      </COMMAND>
    </SWITCH>
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      file=/log/${KLISH_PARAM_fn:-syslog}
      case "$file" in
        *.gz)
          cmd=zcat
          ;;
        *)
          cmd=cat
          ;;
      esac
      if [ -n "$KLISH_PARAM_lines" ]; then
        $cmd "$file" | tail -n $KLISH_PARAM_lines
      else
        $cmd "$file" | pager +G
      fi
    </ACTION>
  </COMMAND>

  <COMMAND name="uptime" help="Show system uptime">
    <ACTION sym="script">uptime</ACTION>
  </COMMAND>
  <!-- TODO hostname, contact, location, base MAC, serial n:o, etc.
    <COMMAND name="system-information" help="Show system information">
    <ACTION sym="script">sysinfo</ACTION>
    </COMMAND>
  -->
  <COMMAND name="version" help="Show software version">
    <ACTION sym="script" in="tty" interrupt="true">cat /etc/version</ACTION>
  </COMMAND>

  <COMMAND name="factory-config" help="Show factory-config">
    <ACTION sym="script" in="tty" out="tty" interrupt="true">copy factory | jq -C . |pager</ACTION>
  </COMMAND>

  <COMMAND name="running-config" help="Show running-config">
    <ACTION sym="script" in="tty" out="tty" interrupt="true">copy running | jq -C . |pager</ACTION>
  </COMMAND>

  <COMMAND name="startup-config" help="Show startup-config">
    <ACTION sym="script" in="tty" out="tty" interrupt="true">copy startup | jq -C . |pager</ACTION>
  </COMMAND>

  <COMMAND name="firewall" help="Show firewall status and configuration">
    <SWITCH name="optional" min="0" max="1">
      <COMMAND name="log" help="Show firewall log (jumps to end), alias to 'show log firewall.log'">
        <SWITCH name="optional" min="0">
          <PARAM name="limit" ptype="/UINT" help="Last N lines, default: all"/>
        </SWITCH>
	<ACTION sym="script" in="tty" out="tty" interrupt="true">
	  copy operational -x /infix-firewall:firewall | /usr/libexec/statd/cli-pretty show-firewall-log $KLISH_PARAM_limit |pager +G
	</ACTION>
      </COMMAND>
      <COMMAND name="matrix" help="Show firewall zone matrix">
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          copy operational -x /infix-firewall:firewall | /usr/libexec/statd/cli-pretty show-firewall-matrix
        </ACTION>
      </COMMAND>
      <COMMAND name="zone" help="Show firewall zones">
        <SWITCH name="optional" min="0">
          <PARAM name="name" ptype="/FIREWALL_ZONES" help="Zone name"/>
        </SWITCH>
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          copy operational -x /infix-firewall:firewall | /usr/libexec/statd/cli-pretty show-firewall-zone "$KLISH_PARAM_name" |pager
        </ACTION>
      </COMMAND>
      <COMMAND name="policy" help="Show firewall policies">
        <SWITCH name="optional" min="0">
          <PARAM name="name" ptype="/FIREWALL_POLICIES" help="Policy name"/>
        </SWITCH>
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          copy operational -x /infix-firewall:firewall | /usr/libexec/statd/cli-pretty show-firewall-policy "$KLISH_PARAM_name" |pager
        </ACTION>
      </COMMAND>
      <COMMAND name="service" help="Show firewall services">
        <SWITCH name="optional" min="0">
          <PARAM name="name" ptype="/FIREWALL_SERVICES" help="Service name"/>
        </SWITCH>
        <ACTION sym="script" in="tty" out="tty" interrupt="true">
          copy operational -x /infix-firewall:firewall | /usr/libexec/statd/cli-pretty show-firewall-service "$KLISH_PARAM_name" |pager
        </ACTION>
      </COMMAND>
    </SWITCH>
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      copy operational -x /infix-firewall:firewall | /usr/libexec/statd/cli-pretty show-firewall |pager
    </ACTION>
  </COMMAND>
</COMMAND>

  <COMMAND name="factory-reset" help="Restore the system to factory default state">
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      /bin/yorn "This will restore the device to factory defaults"
    </ACTION>
    <ACTION sym="srp_rpc@sysrepo">/ietf-factory-default:factory-reset</ACTION>
  </COMMAND>

  <COMMAND name="firewall" help="Control the firewall" mode="switch">
    <COMMAND name="lockdown" help="Emergency lockdown mode">
      <PARAM name="operation" ptype="/STRING" help="Lockdown commands.">
        <COMPL>
          <ACTION sym="printl">now</ACTION>
          <ACTION sym="printl">cancel</ACTION>
        </COMPL>
      </PARAM>
      <ACTION sym="script" in="tty" out="tty" interrupt="true">
	if [ "${KLISH_PARAM_operation}" = "now" ]; then
	  if ! firewall panic status; then
            /bin/yorn -q "WARNING: This will block ALL network traffic and sever existing connections"
	  fi
	fi
      </ACTION>
      <ACTION sym="srp_rpc@sysrepo">/infix-firewall:firewall/lockdown-mode</ACTION>
    </COMMAND>
  </COMMAND>

  <COMMAND name="follow" help="Monitor a log file, use Ctrl-C to abort">
    <PARAM name="fn" ptype="/LOGFILES" help="Optional log file to monitor, default: syslog"/>
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      file=${KLISH_PARAM_fn:-syslog}
      echo -e "\e[1mPress Ctrl-C to abort ────────────────────────────────────────────\e[0m"
      tail -F -n +1 /log/$file
    </ACTION>
  </COMMAND>

  <COMMAND name="netcalc" help="IP subnet calculator, with subnetting">
    <PARAM name="addrlen" ptype="/STRING" help="ADDRESS[/LEN]"/>
    <PARAM name="netmask" ptype="/STRING" min="0" help="Optional NETMASK"/>
    <PARAM name="split"   ptype="/UINT" min="0" help="Split network: 1-32 (IPv4), 1-128 (IPv6)"/>
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      if [ -n "$KLISH_PARAM_split" ]; then
        if echo $KLISH_PARAM_addrlen |grep -q ':'; then
          split="-S $KLISH_PARAM_split"
        else
          split="-s $KLISH_PARAM_split"
        fi
      else
        split=""
      fi
      netcalc $split $KLISH_PARAM_addrlen $KLISH_PARAM_netmask
    </ACTION>
  </COMMAND>

  <COMMAND name="ping" help="Ping a network host or multicast group">
    <SWITCH name="optional" min="0" max="9">
      <COMMAND name="interface" help="Bypass routing table and use this interface">
        <PARAM name="iface" ptype="/IFACES" help="Interface"/>
      </COMMAND>
      <COMMAND name="count" help="Number of packets to send, default: unlimited">
        <PARAM name="cnt" ptype="/UINT"/>
      </COMMAND>
      <COMMAND name="size" help="Define size of empty payload of packets">
        <PARAM name="sz" ptype="/UINT"/>
      </COMMAND>
      <COMMAND name="ttl" help="TTL to set in packets, default: 64 (multicast: 1)">
        <PARAM name="ttl" ptype="/UINT"/>
      </COMMAND>
      <COMMAND name="flood" help="Flood ping mode"/>
    </SWITCH>
    <PARAM name="addr" ptype="/STRING" help="Host address or multicast group"/>
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      count=${KLISH_PARAM_cnt:+-c $KLISH_PARAM_cnt}
      iface=${KLISH_PARAM_iface:+-I $KLISH_PARAM_iface}
      size=${KLISH_PARAM_sz:+-s $KLISH_PARAM_sz}
      ttl=${KLISH_PARAM_ttl:+-t $KLISH_PARAM_ttl}
      flood=${KLISH_PARAM_flood:+-f}
      ping $iface $flood $count $size $ttl $KLISH_PARAM_addr
    </ACTION>
  </COMMAND>

  <COMMAND name="terminal" help="Control the terminal (tty)" mode="switch">
    <COMMAND name="reset" help="Reset terminal settings in case they are garbled">
      <ACTION sym="script" in="tty" out="tty" interrupt="true">
	reset
      </ACTION>
    </COMMAND>
    <COMMAND name="resize" help="Force detect size change after terminal resize">
      <ACTION sym="script" in="tty" out="tty" interrupt="true">
	resize >/dev/null
      </ACTION>
    </COMMAND>
  </COMMAND>

  <COMMAND name="tcpdump" help="Capture network traffic">
    <PARAM name="iface" ptype="/IFACES" help="Interrface to run capture on"/>
    <SWITCH name="optional" min="0" max="7">
      <COMMAND name="count" help="Number of packets to capture, default: unlimited">
        <PARAM name="count" ptype="/UINT"/>
      </COMMAND>
      <COMMAND name="size" help="Number of bytes of each packet to capture">
        <PARAM name="sz"  ptype="/UINT"/>
      </COMMAND>
      <COMMAND name="expression" help="Optional pcap filter expression">
        <PARAM name="expr" ptype="/STRING" help='Filter expression, e.g. "tcp port 80"'/>
      </COMMAND>
      <COMMAND name="verbose" help="Verbose output"/>
    </SWITCH>
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      count=${KLISH_PARAM_cnt:+-c $KLISH_PARAM_cnt}
      size=${KLISH_PARAM_sz:+-s $KLISH_PARAM_sz}
      verbose=${KLISH_PARAM_verbose:+-vvv}
      doas tcpdump -ln $count $size $verbose -i $KLISH_PARAM_iface $KLISH_PARAM_expr
    </ACTION>
  </COMMAND>

  <COMMAND name="upgrade" help="Install a software update bundle from remote or local file">
    <PARAM name="URI" ptype="/STRING" help="[(ftp|tftp|http|https|sftp)://(dns.name | ip.address)/path/to/]upgrade-bundle.pkg"/>
    <SWITCH name="optional" min="0" max="2">
      <COMMAND name="force" help="Force upgrade, ignoring compatibility check."/>
      <COMMAND name="reboot" help="Reboot system after successful upgrade."/>
    </SWITCH>
    <ACTION sym="script" in="tty" out="tty" interrupt="true">
      force=${KLISH_PARAM_force:+--ignore-compatible}
      rauc install $force $KLISH_PARAM_URI
      if [ $? -eq 0 -a -n "$KLISH_PARAM_reboot" ]; then
        echo "Upgrade successful, rebooting..."
        sleep 2
        reboot
      fi
    </ACTION>
  </COMMAND>
</VIEW>

<VIEW name="config">

  <PROMPT>
    <ACTION sym="srp_prompt@sysrepo">%u@%h:%w%x/> </ACTION>
  </PROMPT>

<HOTKEY key="^D" cmd="exit"/>
<HOTKEY key="^Z" cmd="leave"/>

<!-- Move -->

<COMMAND name="abort" help="Abort changes in candidate and return to admin-exec">
  <ACTION sym="srp_reset@sysrepo"/>
  <ACTION sym="nav">replace main</ACTION>
</COMMAND>

<COMMAND name="leave" help="Apply candidate to running-config and return to admin-exec">
  <ACTION sym="srp_commit@sysrepo"/>
  <ACTION sym="srp_top@sysrepo"/>
  <ACTION sym="nav" exec_on="success">replace main</ACTION>
</COMMAND>

<COMMAND name="up" help="Ascend to the parent configuration node">
  <ACTION sym="srp_up@sysrepo"/>
</COMMAND>

<COMMAND name="end" help="Alias to up, leave this subsection/node">
  <ACTION sym="srp_up@sysrepo"/>
</COMMAND>

<COMMAND name="exit" help="Ascend to parent configuration node, or abort (from top)">
  <ACTION sym="srp_up@sysrepo"/>
  <ACTION sym="srp_reset@sysrepo" exec_on="fail" update_retcode="false"/>
  <ACTION sym="nav" exec_on="fail">replace main</ACTION>
</COMMAND>

<COMMAND name="top" help="Ascend to the configuration root">
  <ACTION sym="srp_top@sysrepo"/>
</COMMAND>

<COMMAND name="edit" help="Descend to the specified configuration node">
  <PARAM name="path" ptype="/PLINE_EDIT" max="100"/>
  <ACTION sym="srp_edit@sysrepo"/>
</COMMAND>

<!-- Edit -->

<COMMAND name="text-editor" help="Modify binary content in a text editor">
  <PARAM name="path" ptype="/PLINE_SET" max="100"/>
  <ACTION sym="srp_helper@sysrepo" in="tty" out="tty" interrupt="true"/>
</COMMAND>

<COMMAND name="change" help="Interactively change setting, e.g. password">
  <PARAM name="path" ptype="/PLINE_SET" max="100"/>
  <ACTION sym="srp_helper@sysrepo" in="tty" out="tty" interrupt="true"/>
</COMMAND>

<COMMAND name="set" help="Set configuration setting">
  <PARAM name="path" ptype="/PLINE_SET" max="100"/>
  <ACTION sym="srp_set@sysrepo" in="tty" out="tty" interrupt="true"/>
</COMMAND>

<COMMAND name="delete" help="Delete configuration setting(s)">
  <PARAM name="path" ptype="/PLINE_DEL" max="100"/>
  <ACTION sym="srp_del@sysrepo"/>
</COMMAND>

<COMMAND name="no" help="Alias to delete">
  <PARAM name="path" ptype="/PLINE_DEL" max="100"/>
  <ACTION sym="srp_del@sysrepo"/>
</COMMAND>

<COMMAND name="commit" help="Commit current candidate to running-config">
  <ACTION sym="srp_commit@sysrepo"/>
</COMMAND>

<COMMAND name="reset" help="Reset candidate to running-config">
  <ACTION sym="srp_reset@sysrepo"/>
</COMMAND>

<!-- Display -->

<COMMAND name="check" help="Validate candidate">
  <ACTION sym="srp_verify@sysrepo"/>
</COMMAND>

<COMMAND name="help" help="Show YANG description for setting(s)">
  <PARAM name="path" ptype="/PLINE_SET" max="100" min="0"/>
  <ACTION sym="srp_help_text@sysrepo"/>
</COMMAND>

<COMMAND name="show" help="Show configuration">
  <PARAM name="path" ptype="/PLINE_SET" min="0" max="100"/>
  <ACTION sym="srp_show@sysrepo"/>
</COMMAND>

<COMMAND name="diff" help="Summarize uncommitted changes">
  <PARAM name="path" ptype="/PLINE_SET" min="0" max="100"/>
  <ACTION sym="srp_diff@sysrepo"/>
</COMMAND>

<!-- Misc -->

<COMMAND name="do" help="Execute operational mode command">
  <VIEW name="operational" ref="/main"/>
</COMMAND>

</VIEW>
</KLISH>
