#!/bin/sh

alterator_api_version=1
. alterator-sh-functions
. /usr/lib/alterator-net-iptables/srv.sh

po_domain="alterator-net-iptables"

TCCONF="/etc/alterator/net-tc.conf"

get_mac(){
  local data="${1:-}"
  echo "$data" |
    sed -n 's/^[[:space:]]*[0-9\.]\+=\([a-fA-F0-9:]\+\)[[:space:]].*$/\1/p'
}

on_message()
{
  case "$in_action" in
    list) # list all rules
      set_locale
      local ipmac ip mac services
      write_enum_item "default" "`_ "Default"`"
      iptables_helper ir list |
        while read ipmac services; do
          local ip=${ipmac%%=*}
          [ -z "$ip" ] || echo "$ip"
        done | grep -v default | write_enum
    ;;
    read) # read data for selected ip=mac
      write_bool_param "status" "$(iptables_helper ir status)"
      write_string_param commit_mode "$(iptables_helper show -c)"
      local ifaces="$(iptables_helper show -i | tr -s '\n' ',')"
      write_string_param "ifaces"  "${ifaces%,}"
      [ -n "$in_name" ] || return
      local data="$(iptables_helper ir show "$in_name")"
      local s="$(echo "$data" |\
        sed -n 's/^[[:space:]]*[^[:space:]]\+[[:space:]]\+\(.*\)$/\1/p' |\
        tr ';, ' '\n')"

      write_string_param "services"  "$(echo "$s" | srv_extract srv)"
      write_string_param "tcp_ports" "$(echo "$s" | srv_extract tcp)"
      write_string_param "udp_ports" "$(echo "$s" | srv_extract udp)"
      write_string_param "mac"       "$(get_mac "$data")"
      local ip i o
      grep "^[[:space:]]*$in_name[[:space:]]" "$TCCONF" | (
        read ip i o
        write_string_param "ikbps" "${i:-0}"
        write_string_param "okbps" "${o:-0}"
      )
    ;;
    add)
      set_locale
      local ans="$(iptables_helper ir add "$in_new_ip"  2>&1)"
      [ -z "$ans" ] || write_error "${ans#iptables_helper*:}"
    ;;
    switch)
      set_locale
      local status
      if [ "$in_status" = "#t" ]; then
        local ans="$(iptables_helper ir on  2>&1)"
        [ -z "$ans" ] || write_error "${ans#iptables_helper*:}"

        if [ "$(iptables_helper show -c)" != "off" ]; then
          ans="$(alterator-net-tc restart > /dev/null 2>&1)"
          [ -z "$ans" ] || write_error "${ans#alterator-net-tc*:}"
        fi

      else
        local ans="$(iptables_helper ir off  2>&1)"
        [ -z "$ans" ] || write_error "${ans#iptables_helper*:}"

        if [ "$(iptables_helper show -c)" != "off" ]; then
          ans="$(alterator-net-tc stop)"
          [ -z "$ans" ] || write_error "${ans#alterator-net-tc*:}"
        fi
      fi
    ;;
    resolve)
      ping -w1 -c1 -q "$in_name" &>/dev/null
      local mac="$(arp -n -a "$in_name" |\
      sed -n 's/.* at \([0-9a-zA-Z:]\+\) .*/\1/p')"
      write_string_param "mac" "$mac"
    ;;
    del)
      [ -n "$in_name" ] || return
      set_locale
      local ans="$(iptables_helper ir del "$in_name" 2>&1)"
      [ -z "$ans" ] || write_error "${ans#iptables_helper*:}"
      sed -i "/^[[:space:]]*$in_name[[:space:]].*/d" "$TCCONF"
    ;;
    write)
      set_locale
      local ans
      local services="$(srv_compile "$in_services" "$in_tcp_ports" "$in_udp_ports")"

      [ -n "$in_name" ] || {
        write_error "`_ "IP-address is not specified"`"
        return
      }

      ans="$(iptables_helper ir add "$in_name${in_mac:+=$in_mac} $services"  2>&1)"
      [ -z "$ans" ] || write_error "${ans#iptables_helper*:}"

      if [ "$in_name" != default ]; then
        if grep -s "^[[:space:]]*$in_name[[:space:]]" "$TCCONF"; then
          sed -i "s/^\([[:space:]]*$in_name[[:space:]]\+\).*/\1${in_ikbps:-0} ${in_okbps:-0}/" "$TCCONF"
        else
          echo "$in_name ${in_ikbps:-0} ${in_okbps:-0}" >> "$TCCONF"
        fi
        ans="$(alterator-net-tc restart >/dev/null 2>&1)"
        [ -z "$ans" ] || write_error "${ans#alterator-net-tc*:}"
      fi
    ;;
  esac
}

message_loop
