#!/bin/sh
# Displays basic information about the system
# shellcheck disable=SC2048,SC2086
. /etc/os-release

bopt="-c"
opt="-br"
all=""
plain=""

TTY=$(resize)
eval "$TTY"

# COLUMS and ROWS should be set on the console, if not, use fallback
if [ -z "$COLUMNS" ]; then
	if command -v tput; then
		COLUMNS=$(tput cols)
	else
		COLUMNS=80
	fi
fi

h1()
{
	STR="$*"
	if [ -n "$plain" ]; then
		echo "$STR" | tr '[:lower:]' '[:upper:]'
	else
		printf "\033[7m%-${COLUMNS}s\033[0m\n" "$STR"
	fi
}

h2()
{
	STR="$*"
	if [ -n "$plain" ]; then
		echo "$STR"
		echo "$STR" | sed 's/./-/g'
	else
		printf "\033[1m%-${COLUMNS}s\033[0m\n" "$STR"
	fi
}

dm()
{
	if [ -n "$plain" ]; then
		echo "${*}"
	else
		printf "\033[2m%s\033[0m\n" "$*"
	fi
}

ul()
{
	if [ -n "$plain" ]; then
		printf "__%s__" "$*"
	else
		printf "\033[4%s\033[0m" "$*"
	fi
}

em()
{
	if [ -n "$plain" ]; then
		printf "**%s**" "$*"
	else
		printf "\033[5m%s\033[0m" "$*"
	fi
}

usage()
{
	cat <<EOF
usage:
  show [opt] cmd

options:
  -a            Show all, of something
  -f            Show full output, not brief port/iface listings
  -h            Show this help text
  -n            Show output without any footer
  -p            Show plain output, no bells or whistles

commands:
  port PORT     Show port configuration and link information
  ports         Show ports available for bridging
  vlans         Show port groups in bridge
  ifaces        Show interfaces and their addresses
  fdb           Show forwarding database (unicast)
  mdb           Show multicast forwarding database
  ip route      Show routing table
  log [FILE]    Show latest entries from syslog, or other FILE
  rmon PORT     Show RMON counters for PORT (when applicable)
  system        Show OS details
  version       Show OS verson
EOF
}

# Usage 1: show port eth0
# Usage 2: show port
# Usage 3: show ports
#
# The first show ethtool output for 'eth0' (in this case).  The latter
# two are the same, showing a summary of all interfaces classified as
# access ports.
ports()
{
	if [ $# -gt 0 ] && [ -e "/sys/class/net/$1" ]; then
		for port in $*; do
			ethtool "$port"
		done
		return
	fi

	h1 "PORT             STATE          MAC ADDRESS        FLAGS"
	if grep -q port /etc/iproute2/group && [ -z "$all" ]; then
		ip $opt link show group port
	else
		ip $opt link show
	fi

	if [ -z "$plain" ] && [ -z "$nofoot" ]; then
		dm "______________________________________________________________________________"
		dm "Use: '[ip|bridge] --help' and '[ip|bridge] link help' for more details."
	fi
}

vlans()
{
	h1 "INTERFACE         VLAN  FLAGS"
	bridge $bopt vlan show |tail +2 | awk 'NF { iface=$1; vid=$2; printf("%-16s  %4d  ", iface, vid); for (i=3; i <= NF; i++) printf("%s ", $i); printf("\n"); }'
	if [ -z "$plain" ] && [ -z "$nofoot" ]; then
		dm "______________________________________________________________________________"
		dm "See: 'bridge --help' and 'bridge vlan help' for more details."
	fi
}

ifaces()
{
	h1 "INTERFACE        STATE          ADDRESS"
	if [ -n "$all" ]; then
		ip $opt addr show
        elif grep -q iface /etc/iproute2/group; then
                ip $opt addr show group iface
	else
		ip $opt addr show |awk '{ if ($1 !~ /eth[0-9]*/ && $1 !~ /.*@NONE/) { print }}'
	fi
	if [ -z "$plain" ] && [ -z "$nofoot" ]; then
		dm "______________________________________________________________________________"
		dm "See: 'ip --help' and 'ip address help' for more details."
	fi
}

log()
{
	if [ -n "$1" ] && [ -r "/var/log/$1" ]; then
		fn="/var/log/$1"
	else
		fn="/var/log/syslog"
	fi
	if [ -n "$all" ]; then
		cat $fn
	else
		tail -$LINES $fn
	fi
	if [ -z "$plain" ] && [ -z "$nofoot" ]; then
		dm "______________________________________________________________________________"
		dm "See: 'tail -25 /log/FILE', 'tail -F /log/FILE' to continuously monitor files."
	fi
}

rmon()
{
	if [ -z "$*" ]; then
		echo "Missing argument, see 'show port' for available interfaces"
		exit 1
	fi
	for port in $*; do
		ethtool -S "$port"
	done
	if [ -z "$plain" ] && [ -z "$nofoot" ]; then
		dm "______________________________________________________________________________"
		dm "See: 'ethtool --help' for more details."
	fi
}

rstp()
{
	mstpctl showbridge
	echo "br0 port info"
	mstpctl showport br0
}

fdb()
{
	bridge $bopt fdb show
}

mdb()
{
	bridge $bopt mdb show
}

routes()
{
	ip $opt route show
}

igmp()
{
	querierctl $@
}

system()
{
	h1 "SYSTEM INFORMATION"
	echo "System Name        : $(uname -n)"
	echo "System Variant     : $VARIANT"
	echo "System Description : $PRETTY_NAME"
	echo "System Contact     : $HOME_URL"
	echo "System Timezone    : $(cat /etc/timezone)"
	echo "System Type        : $NAME"
	echo "System Version     : $(cat /etc/version)"
	echo "System Arch        : $(uname -m)"
	echo "Kernel Version     : $(uname -sr)"
}

version()
{
	cat /etc/version
}

while [ "$1" != "" ]; do
	case $1 in
		-a)
			all=1
			;;
		-f)
			opt=""
			if [ -n "$plain" ]; then
				opt="-color=never"
				bopt="-color=never"
			fi
			;;
		-n)
			nofoot="yes"
			;;
		-p)
			plain="yes"
			opt="$opt -color=never"
			bopt="$bopt -color=never"
			;;
		-h)
			usage
			exit 0
			;;
		*)
			break
	esac
	shift
done

cmd=$1
if [ -n "$cmd" ]; then
	shift
fi

case $cmd in
	help)
		usage
		;;
	port*)
		ports $*
		;;
	vlan*)
		vlans
		;;
	fdb)
		fdb
		;;
	mdb)
		mdb
		;;
	if*)
		ifaces
		;;
	ip)
		cmd=$1
		shift
		case $cmd in
			addr*)
				ifaces
				;;
			route*)
				routes
				;;
			igmp*)
				igmp $*
				;;
			*)
				usage
				;;
		esac
		;;
	log)
		log $1
		;;
	rmon)
		rmon $*
		;;
	route*)
		routes
		;;
	span*)
		rstp
		;;
	sys*)
		system
		;;
	ver*)
		version
		;;
	*)
		usage
		exit 1
		;;
esac
