#!/bin/sh
. /usr/share/libubox/jshn.sh

FILE=/tmp/clientlist.json
CLEANUP_TIME=$((7*24*60*60))    # one week
UPTIME=$(cut -d. -f1 < /proc/uptime)
CMD="$1"
MAC="$2"
RADIO="$3"
SSID="$4"

PROPAGATE_CHANGES=""

add_object () {
    json_add_object
    json_add_string mac "$MAC"
    json_add_string radio "$RADIO"
    json_add_string ssid "$SSID"
    json_add_int connected 1
    json_add_int time_stamp "$UPTIME"
    json_close_object
}

remove_object () {
    unset ${JSON_CUR}_${1}
}

connect_client () {
    local CONNECTED="$(cat ${FILE} | jsonfilter -e "@.clients[@.mac=\"${MAC}\"].connected")"
    if [ -z "${CONNECTED}" ] || [ "${CONNECTED}" = "0" ]; then
        PROPAGATE_CHANGES="1"
        json_init
        if [ ! -f "$FILE" ]; then
            json_add_array "clients"
            add_object
            json_close_array
        else
            local Idx="$(cat ${FILE} | jsonfilter -e '@.clients[@].mac' | grep ${MAC} -n | cut -d':' -f1)"
            json_load "$(cat $FILE)"
            json_select "clients"
            if [ -z "${Idx}" ]; then
                add_object
            else
                json_select $Idx
                json_add_string radio "$RADIO"
                json_add_string ssid "$SSID"
                json_add_int connected 1
                json_add_int time_stamp "$UPTIME"
            fi
        fi
        json_dump > $FILE
    fi
}

disconnect_client () {
    local CONNECTED="$(cat ${FILE} | jsonfilter -e "@.clients[@.mac=\"${MAC}\"].connected")"
    if [ "${CONNECTED}" = "1" ]; then
        PROPAGATE_CHANGES="1"
	local Idx="$(cat ${FILE} | jsonfilter -e '@.clients[@].mac' | grep ${MAC} -n | cut -d':' -f1)"
	if [ ! -z "${Idx}" ]; then
	    json_init
            json_load "$(cat $FILE)"
            json_select "clients"
            json_select $Idx
            local time_stamp persist
            json_get_var time_stamp time_stamp
            json_get_var persist persist
            if [ $(($UPTIME-$time_stamp)) -le 5 ] && [ "$persist" != "1" ]; then
		json_add_int connected -1
            else
		json_add_int persist 1
		json_add_int connected 0
            fi
	    json_dump > $FILE
	fi
    fi
}

read_list () {
    local SSID="$1"
    json_init
    if [ -e "$FILE" ]; then
        json_load "$(cat $FILE)"
    fi
    json_dump
}

cleanup_list () {
    if [ ! -e "$FILE" ]; then
        echo "No client list found"
        return
    fi
    json_init
    json_load "$(cat $FILE)"
    json_select clients
    local Idx=1
    while json_get_type type $Idx && [ "$type" = object ]; do
        json_select $Idx
        local ts
        json_get_var ts time_stamp
        json_select ..
        if [ $(($UPTIME-$ts)) -gt $CLEANUP_TIME ]; then
            remove_object $Idx
        fi
        Idx=$((Idx+1))
    done
    json_dump > $FILE
}

show_list () {
    if [ ! -e "$FILE" ]; then
        echo "No client list found"
        return
    fi
    json_init
    json_load "$(cat $FILE)"
    json_select clients
    echo "   MAC Address         Date/time             Online  Radio  SSID"
    local Idx=1
    while json_get_type type $Idx && [ "$type" = object ]; do
        local mac radio ssid connected ts
        json_select $Idx
        json_get_var mac mac
        json_get_var radio radio
        json_get_var ssid ssid
        json_get_var connected connected
        json_get_var ts time_stamp
        echo "$Idx: $mac   $(date +%F_%X -d @$(($(date +%s)-$ts)))   $connected        $radio      $ssid"
        json_select ..
        Idx=$((Idx+1))
    done
}

case "$CMD" in
    assoc)
        connect_client
        [ -z "${PROPAGATE_CHANGES}" ] || /usr/bin/station_quota.sh --event "${CMD}" --mac "${MAC}"
        ;;
    cleanup)
        cleanup_list
        ;;
    disassoc)
        disconnect_client
        [ -z "${PROPAGATE_CHANGES}" ] || /usr/bin/station_quota.sh --event "${CMD}" --mac "${MAC}"
        ;;
    read)
        read_list $2
        ;;
    show)
        show_list
        ;;
    *)
        echo "$0 <command> <MAC> <radio> <ssid>"
        echo
        echo "commands:"
        echo "    assoc    <MAC> <radio> <ssid>"
        echo "    cleanup"
        echo "    disassoc <MAC>"
        echo "    read"
        echo "    show"
        ;;
esac
