#!/bin/bash

CYAN='\033[0;36m' # Used in headers
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color

GREY_BG="\e[48;5;235m"
RESET="\e[0m"

HEADER_WIDHT=80
declare -A IETF_TYPE_MAP

IETF_TYPE_MAP["iana-if-type:softwareLoopback"]="loopback"
IETF_TYPE_MAP["iana-if-type:ethernetCsmacd"]="ethernet"
IETF_TYPE_MAP["iana-if-type:l2vlan"]="vlan"
IETF_TYPE_MAP["infix-if-type:veth"]="veth"
IETF_TYPE_MAP["iana-if-type:bridge"]="bridge"

usage() {
    printf "Please provide a valid base field as the first argument\n"
    exit 1
}

if [ -z "$1" ]; then
    usage
fi

json=$(cat)

show_ietf_interface() {
    name="$1"
    shift

    iface=$(echo "$json" | jq --arg name "$name" \
            '.["ietf-interfaces:interfaces"].interface[] | select(.name == $name)')
    if [ -z "$iface" ]; then
        printf "Error, interface named \"$name\" not found"
        exit 1
    fi

    printf "%-20s : %s\n" "name" "$name"
    printf "%-20s : %s\n" "interface-index" "$(echo "$iface" | jq -r '.["if-index"]')"
    printf "%-20s : %s\n" "operational-status" "$(echo "$iface" | jq -r '.["oper-status"]')"
    printf "%-20s : %s\n" "physical-address" "$(echo "$iface" | jq -r '.["phys-address"]')"

    # MTU isn't set for loopback
    mtu="$(echo "$iface" | jq -r '.["ietf-ip:ipv4"] | select(.mtu != null) | .mtu')"
    if [ -n "$mtu" ]; then
        printf "%-20s : %s\n" "mtu" "$mtu"
    fi

    printf "\n${CYAN}%-5s${NC}\n" "ipv4:"
    addresses=$(echo "$iface" | jq -c --arg field "$field" '.["ietf-ip:ipv4"].address[]' 2>/dev/null)
    for addr in $addresses; do
        ip="$(echo "$addr" | jq -r '."ip"')"
        prefix="$(echo "$addr" | jq -r '."prefix-length"')"
        printf "%-5s %s/%s\n" "" "$ip" "$prefix"
    done

    printf "\n${CYAN}%-5s %5s\n${NC}" "in:" "octets"
    printf "%-5s %s\n" "" "$(echo "$iface" | jq -r '.statistics["in-octets"]')"

    printf "\n${CYAN}%-5s %5s${NC}\n" "out:" "octets"
    printf "%-5s %s\n" "" "$(echo "$iface" | jq -r '.statistics["out-octets"]')"
}

show_ietf_interfaces() {
    field="ietf-interfaces:interfaces"

    if [ $# -ne 0 ]; then
        show_ietf_interface "$1"
        return
    fi

    interfaces=$(echo "$json" | jq -c --arg field "$field" '.[$field].interface[]')

    HEADER=$(printf "%-15s %-14s %-25s %s\n" "INTERFACE" "STATE" "PROTOCOL/ADDRESS" "SOURCE")
    HEADER_LEN=${#HEADER}
    RIGHT_PADDING=$(( HEADER_WIDHT - HEADER_LEN ))

    printf "${GREY_BG}%s%${RIGHT_PADDING}s${RESET}\n" "$HEADER" ""

    for iface in $interfaces; do
        name="$(echo "$iface" | jq -r '.["name"]')"
        state="$(echo "$iface" | jq -r '.["oper-status"]')"
        mac="$(echo "$iface" | jq -r '.["phys-address"]')"
        type="$(echo "$iface" | jq -r '.["type"]')"
        state_color=""

        if [[ -v IETF_TYPE_MAP["$type"] ]]; then
            src="${IETF_TYPE_MAP["$type"]}"
        else
            src="unknown"
        fi

        if [ "$state" = "up" ]; then
            state_color="$GREEN"
        elif [ "$state" = "down" ]; then
            state_color="$RED"
        fi
        printf "%-15s ${state_color}%-15s${NC}%s" "$name" "$state"

        addresses=$(echo "$iface" | jq -c --arg field "$field" '.["ietf-ip:ipv4"].address[]' 2>/dev/null)
        printf "%-25s %s\n" "$mac" "$src"
        for addr in $addresses; do
            ip="$(echo "$addr" | jq -r '."ip"')"
            prefix="$(echo "$addr" | jq -r '."prefix-length"')"
            printf "%-30s %s/%s\n" "" "$ip" "$prefix"
        done
        if [ -n "$addresses" ]; then
            printf "\n"
        fi
    done
}

field="$1"
shift

case "$field" in
    "ietf-interfaces")
        show_ietf_interfaces $*
        ;;
    *)
        usage
        ;;
esac
