#!/bin/sh

po_domain="alterator-net-wifi"
alterator_api_version=1
. alterator-sh-functions
. alterator-hw-functions
. shell-config

NMCLI=/usr/bin/nmcli
#########


list_scan_results()
{
    echo "$($NMCLI -f BSSID,SIGNAL,SSID d wifi list ifname $in_iface | sed '1d')" |\
      while read bssid level ssid; do
          echo "$ssid $ssid / $level / $bssid"
      done
}

list_networks()
{
    LANG=C $NMCLI -t --fields 'NAME, ACTIVE, UUID, TYPE' c show | grep 802-11-wireless |\
    while read rec
    do
        name="$(echo $rec | cut -d: -f 1)"
        uuid="$(echo $rec | cut -d: -f 3)"
        [[ "$($NMCLI -g GENERAL.STATE c show $uuid)" == activat* ]] && active="+" || active="-"
        ssid="$($NMCLI -g 802-11-wireless.ssid c show $uuid)"
        label="$active $name [$ssid]"
        echo "$uuid $label"
    done
}

list_auth_types()
{
    echo "_"  "`_ "No password"`"
    echo "none" "`_ "WEP Password"`"
    echo "wpa-psk" "`_ "WPA Personal (WPA-PSK)"`"
}

#network information
get_network()
{
    [ -n "$in_uuid" ] || return
    uuid="$in_uuid"
    # autoconnect="$($NMCLI -g connection.autoconnect c show $uuid)"
    ssid="$($NMCLI -g 802-11-wireless.ssid c show $uuid)"
    name="$($NMCLI -g connection.id c show $uuid)"
    key_mgmt="$($NMCLI -g 802-11-wireless-security.key-mgmt c show $uuid)"
    [ -n "$key_mgmt" ] || key_mgmt="_"
    current="no"
    [[ "$($NMCLI -g GENERAL.STATE c show $uuid)" == activat* ]] && current="yes"
    write_string_param "name" "$name"
    write_string_param "uuid" "$uuid"
    # write_bool_param "autoconnect" "$autoconnect"
    write_bool_param "current" "$current"
    write_string_param "essid" "$ssid"
    write_string_param "auth_type" "$key_mgmt"
    key=""
    case "$key_mgmt" in
        none)
            key="$($NMCLI --show-secrets -g 802-11-wireless-security.wep-key0 c show $uuid)"
            ;;
        wpa-psk)
            key="$($NMCLI --show-secrets -g 802-11-wireless-security.psk c show $uuid)"
            ;;
    esac
    write_string_param "key" "$key"
}

network_remove()
{
    [ -n "$in_uuid" ] || return
    $NMCLI c delete "$in_uuid"
}

network_save()
{
    ssid="$($NMCLI -g 802-11-wireless.ssid c show $in_uuid)"
    name="$($NMCLI -g connection.id c show $in_uuid)"

    [ "$in_name" == "$name" -a "$ssid" == "$in_essid" ] || $NMCLI c modify "$in_uuid" \
    connection.id "$in_name" \
    802-11-wireless.ssid "$in_essid"

    [ "$in_auth_type" == "_" ] && key_mgmt="" || key_mgmt="$in_auth_type"
    [ -n "$key_mgmt" ] || return

    old_key_mgmt="$($NMCLI -g 802-11-wireless-security.key-mgmt c show $in_uuid)"
    [ "$old_key_mgmt" == "$key_mgmt" ] || $NMCLI c modify "$in_uuid" \
    802-11-wireless-security.key-mgmt "$key_mgmt"

    [ -n "$in_key" ] || return

    kl=${#in_key}
    ishex=$(echo "$in_key" | grep -c -E "^[a-fA-F0-9]+$")
    case "$key_mgmt" in
        none)
            if [ $kl == 10 -o $kl == 26 ] && [ $ishex == 1 ] || [ $kl == 5 -o $kl == 13 ]
            then
                $NMCLI c modify "$in_uuid" 802-11-wireless-security.wep-key0 "$in_key"
            else
                write_error "`_ "Bad format password"`"
            fi
            ;;
        wpa-psk)
            if [ $kl == 64 ] && [ $ishex == 1 ] || [ $kl -lt 64 -a $kl -gt 7 ]
            then
                $NMCLI c modify "$in_uuid" 802-11-wireless-security.psk "$in_key"
            else
                write_error "`_ "Bad format password"`"
            fi
            ;;
    esac

    [ "$in_connect" = "#t" ] && network_connect
}

network_new()
{
    [ -n "$in_name" ] && name="$in_name" || name="NEW_NETWORK"
    $NMCLI connection add type wifi ifname "$in_iface" \
    con-name "$name" \
    wifi.ssid "$name" \
    connection.autoconnect "yes"

    $NMCLI device set "$in_iface" autoconnect "yes"
}

network_connect()
{
    [ -n "$in_uuid" ] || return
    $NMCLI con up "$in_uuid" || write_error "`_ "Connection error"`"
}

network_disconnect()
{
    [ -n "$in_uuid" ] || return
    $NMCLI con down "$in_uuid"
}

configure_interface()
{
    local iface="$1"
    local ifacedir="/etc/net/ifaces/$iface"
    local options="$ifacedir/options"

    [ -d "$ifacedir" ] || mkdir "$ifacedir"

    shell_config_set "$options" "DISABLED" "yes"
    shell_config_set "$options" "NM_CONTROLLED" "yes"
    shell_config_set "$options" "CONFIG_WIRELESS" "yes"
}

configured_iface=

on_message()
{
    if [ "$in_action" = "read" -o "$in_action" = "write" -o "$in_action" = "list" ]; then
        if [ -z "$in_iface" ] || ! netdev_is_wireless "$in_iface"; then
            write_error "`_ "Not a wireless interface"`"
            return
        fi
    fi

    if [ -n "$in_iface" -a "$in_iface" != "$configured_iface" ]; then
        configure_interface "$in_iface"
        configured_iface="$in_iface"
    fi

    case "$in_action" in

    list)
      case "${in__objects}" in
        scan)
          list_scan_results | write_enum
          write_enum_item "" "`_ "Other network"`"
        ;;
        networks)       list_networks        | write_enum ;;
        auth_types)     list_auth_types      | write_enum ;;
      esac
    ;;

    read)
        get_network
    ;;

    write)
        case "${in__objects}" in
            remove)
                network_remove
            ;;
            save)
                network_save
            ;;
            new)
                network_new
            ;;
            # connect)
            #     network_connect
            # ;;
            disconnect)
                network_disconnect
            ;;
        esac
    ;;

  esac
}

message_loop
