#!/bin/sh -u

cachedir="/var/cache/alterator/net-eth"

alterator_api_version=1

. alterator-sh-functions
. alterator-net-functions
. alterator-hw-functions

###
next_vlan_iface()
{
	local host="$1"; shift
	local i=1
	local path1="/etc/net/ifaces/$host."
	local path2="$cachedir/$host."

	[ -n "$host" ] || return

	while true; do
		[ -d "$path1$i" -o -d "$path2$i" ] || { echo "$host.$i" && break; }
		iface_will_removed "$cachedir" "$host.$i" && { echo "$host.$i" && break; }
		i=$(($i + 1))
		[ $i -le 4095 ] || break
	done
}

add_vlan()
{
	local host="$1"; shift
	local vid="$1"; shift
	local name="$host.$vid"

	if [ -z "$host" ] ; then
		return
	fi

	if ! ( [ -n "${vid##0*}" -a -n "${vid##*[!0-9]*}" ] && [ "$vid" -gt 0 -a "$vid" -le 4095 ] 2>/dev/null ); then
		write_error "`_ "Bad VLAN ID: $vid"`"
		return
	fi

	if iface_will_removed "$cachedir" "$name"; then
		rm -r -- "$cachedir/$name/"
	elif [ -d "$cachedir/$name" -o -d "/etc/net/ifaces/$name" ]; then
		write_error "`_ "$name already exists"`"
		return
	fi

	mkdir -p -- "$cachedir/$name"

	cat > "$cachedir/$name/options" <<OPTIONS_TEMPLATE
TYPE=vlan
HOST=$host
VID=$vid
ONBOOT=yes
CONFIG_WIRELESS=no
CONFIG_IPV4=yes
CONFIG_IPV6=no
BOOTPROTO=static
NM_CONTROLLED=no
OPTIONS_TEMPLATE

	write_string_param "new_vlan" "$name"
}

read_vlan()
{
	local name="$1"; shift
	local ifacedir="$(ifacedir_with_cache "$cachedir" "$name")"

	if [ -z "$name" ]; then
		return
	fi

	if iface_will_removed "$cachedir" "$name"; then
		# Removed, do not print anything
		return
	fi

	vid="$(read_iface_option "$ifacedir" "VID")"
	write_string_param "vlan_vid" "$vid"
}

on_message()
{
	case "$in_action" in

		list)
			case "${in__objects##*/}" in
			    iface_vlans) list_vlans_for_iface_with_cache "$cachedir" "$in_iface" | write_enum
					;;
			esac
			;;
		read)
			case "$in__objects" in
				/)
					read_vlan "$in_vlan_name"
					;;
				new_vlan)
					add_vlan "$in_iface" "$in_vid"
					;;
			esac
			;;
		write)
			case "$in__objects" in
				/)
					;;
				rm_vlan)
					remove_iface_with_cache "$cachedir" "$in_vlan_name"
					;;
			esac
			;;
	esac
}

message_loop
