#!/bin/sh

. alterator-sh-functions

PATH="/usr/libexec/alterator-nut/:$PATH"
UPS_CONF="/etc/nut/ups.conf"

po_domain="alterator-nut"

vendor=
model=

inireplace()
{
    local object="$1" && shift
    local name="$1" && shift
    local value="$1" && shift

    sed -r "s,(^$object:[[:space:]]*$name[[:space:]]*)=.*,\1=$value,"
}

replace_conf()
{
    chmod 640 "$UPS_CONF.new"
    chown 'root:upsdrv' "$UPS_CONF.new"
    mv -f "$UPS_CONF" "$UPS_CONF.bak"
    mv -f "$UPS_CONF.new" "$UPS_CONF"
}

status_name()
{
    case "$1" in
        OFF) _ "Off";;
        OL) _ "On-line";;
        OB) _ "On battery";;
        LB) _ "Low battery";;
        RB) _ "Replace battery";;
        OVER) _ "Overload";;
        TRIM) _ "Voltage trim";;
        BOOST) _ "Voltage boost";;
        CAL) _ "Calibartion";;
        BYPASS) _ "Bypass";;
        *)	echo "$1" ;;
    esac
}

ups_status()
{
    set -- $(upsc "$1" "ups.status" || _ "N/A")
    for i; do status_name "$i"; echo -n ' ';done
}

on_message(){
  case "$in_action" in
  constraints)
    echo '('
     if [ "$in__objects" != devices -a "$in__objects" != drivers ]; then
         printf 'name (required #t match ("^[a-z][a-z0-9]+$" "%s") label "%s")' \
           "`_ "should be digits and small latin letters"`" "`_ "Name"`"
         printf 'driver (required #t label "%s" default "genericups")' "`_ "Driver"`"
      fi
    echo ')'
    ;;
  list)
    case "$in__objects" in
    /)
      echo '('
      iniread "$UPS_CONF" |
        grep '^\[start\]' |
        cut -f2 -d: |
        sed 's,.*,("&"),'
      echo ')'
      ;;
    vendors)
      echo '('
      drvlist |
        cut -d';' -f1 |
        sort -u |
        sed 's,.*,("&"),'
      echo ')'
      ;;
    models)
      echo '('
      drvlist |
        grep "^${in_name:-${vendor:-"AEC"}};"|
        cut -d';' -f2|
        sed 's,.*,("&"),'
      echo ')'
      ;;
    devices)
      echo '('
      devlist | write_enum
      echo ')'
      ;;
    *)
      echo '()'
      ;;
    esac
    ;;
  read)
    if [ "$in__objects" == "/" ]; then
      echo '()'
    elif [ "$in__objects" == "drivers" -a -n "$in_device" ]; then
      echo '('
      write_string_param  name   "$vendor"
      write_string_param  model  "$model"
      write_string_param  device "$in_device"
      echo ')'
    elif [ "$in__objects" == "devices" -a -n "$in_device" ]; then
      echo '('
      write_string_param  device "$in_device"
      write_string_param  port   "$in_port"
      echo ')'
    else
      vendor=
      model=
      local cfgout=$(iniread "$UPS_CONF"|grep "^$in__objects:"|cut -f2 -d':')
      local driver=$(echo "$cfgout"|sed -n '/driver/ {s,[[:space:]]*driver[[:space:]]*=[[:space:]]*,,;p}')
      local port=$(echo "$cfgout"|sed -n '/port/ {s,[[:space:]]*port[[:space:]]*=[[:space:]]*,,;p}')

      echo '('
      write_string_param  name   "$in__objects"
      write_string_param  model  "$model"
      write_string_param  driver "$driver"
      write_string_param  port   "$port"
      write_string_param  status "$(ups_status "$in__objects@localhost")"
      write_string_param  charge "$(upsc "$in__objects@localhost" "battery.charge" || echo "0")%"
      write_string_param  load   "$(upsc "$in__objects@localhost" "ups.load" || echo "0")%"
      echo ')'
    fi

    ;;
  write)
    #read
    local out="$(iniread "$UPS_CONF")"

    #modify
    if [ "$in__objects" = "drivers" -a -n "$in_device" ]; then
      if [ -z "$in_commit" ]; then
        printf '()'
        return
      fi
      vendor="$in_name"
      model="$in_model"
      local driver="$(drvlist|grep "^$vendor;$model[[:space:]]*;"|cut -f3 -d';')"
      out="$(echo "$out"|inireplace "${in_device}" "driver" "$driver")"

    elif [ "$in__objects" = "devices" -a -n "$in_device" ]; then
      if [ -z "$in_commit" ]; then
        printf '()'
        return
      fi
      local cfgout=$(iniread "$UPS_CONF"|grep "^$in_device:"|cut -f2 -d':')
      local driver=$(echo "$cfgout"|sed -n '/driver/ {s,[[:space:]]*driver[[:space:]]*=[[:space:]]*,,;p}')
      if [ -z "$driver" ]; then
        driver=genericups
        [ "${in_port#/dev/tty}" = "$in_port" ] && driver=newhidups
      fi
      out="$(echo "$out"|inireplace "$in_device" "driver" "$driver")"
      out="$(echo "$out"|inireplace "$in_device" "port"   "$in_port")"
    else
      device="$in_name"
      [ -n "$in_driver" ] &&
        out="$(echo "$out"|inireplace "$device" "driver" "$in_driver")"
      [ -n "$in_port" ] &&
        out="$(echo "$out"|inireplace "$device" "port" "$in_port")"
    fi

    #write
    echo "$out"|iniwrite >"$UPS_CONF.new"
    replace_conf

    echo '()'
    ;;
  new)
    if iniread "$UPS_CONF"|egrep -qs "^\[start\]:$in_name$"; then
      write_error "`_ "Same device already exists"`"
    else
      device="$in_name"
      #append new entry to config file
      echo "[$device]" >>$UPS_CONF
      echo "	port=$in_port" >>$UPS_CONF
      echo "	driver=$in_driver" >>$UPS_CONF
      echo '()'
    fi
    ;;
  delete)
    #filter entry from config file
    iniread "$UPS_CONF" |
      egrep -v "(^\[start\]:$in__objects$|^$in__objects:)" |
      iniwrite >"$UPS_CONF.new"
    replace_conf
    echo '()'
    ;;
  *)
    echo '#f'
    ;;
  esac
}

message_loop
