#!/bin/bash -efu

[ "$1" = start ] || exit 0

. /.initrd/initenv
. /etc/init.d/functions
. shell-ip-address
. network-sh-functions
. network-cmdline-sh-functions

lower_before_char()
{
	local part="${2%%$1*}"
	if [ "$part" != "$2" ]; then
		printf '%s%s%s\n' "${part,,}" "$1" "${2#*$1}"
	else
		printf '%s\n' "$2"
	fi
}

get_version()
{
	local i="${2-}"
	case "$1" in
		*.*.*.*) i=4 ;;
		*:*:*)   i=6 ;;
	esac
	ip_version=$i
}

configure()
{
	if [ "${NAMESERVER:-0}" != 0 ]; then
		printf '# cmdline nameservers start\n' > /etc/resolv.conf
		i=0
		while [ $i -lt ${NAMESERVER:-0} ]; do
			eval "OPTS=\"\$NAMESERVER$i\""
			OPTS="${OPTS#[}"
			OPTS="${OPTS%]}"
			printf 'nameserver %s\n' "$OPTS"
			i=$(($i+1))
		done >> /etc/resolv.conf
		printf '# cmdline nameservers end\n' >> /etc/resolv.conf
	fi

	i=0
	while [ $i -lt ${IFNAME:-0} ]; do
		eval "ifname_to_var \"\$IFNAME$i\""

		# udev requires MAC addresses to be lower case
		macaddr="$(lower_before_char '=' "$macaddr")"

		printf 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="%s", ATTR{dev_id}=="0x0", ATTR{type}=="1", NAME="%s"\n' \
			"$macaddr" "$interface" >> /etc/udev/rules.d/60-persistent-net.rules

		i=$(($i+1))
	done

	i=0
	while [ $i -lt ${IP:-0} ]; do
		eval "ip_to_var \"\$IP$i\""

		dir=
		[ "${#interface}" != 0 ] &&
			dir="$net_confdir/ifaces/$interface" ||
			dir="$net_confdir/default"

		rm -rf -- "$dir"
		mkdir -p -- "$dir"

		case "$autoconf" in
			none|off|static)
				;;
			on|any|dhcp)
				:> "$dir/ipv4dhcp"
				:> "$dir/ipv6dhcp"
				;;
			dhcp4)
				:> "$dir/ipv4dhcp"
				;;
			dhcp6)
				:> "$dir/ipv6dhcp"
				;;
			*)
				fatal "unknown autoconf value: $autoconf"
				;;
		esac

		:> "$dir/options"
		:> "$dir/iplink"

		[ "${#macaddr}" = 0 ] || [ "${#interface}" = 0 ] ||
			printf "set address %s\n" "$(lower_before_char '=' "$macaddr")" >> "$dir/iplink"

		[ -z "$mtu" ] ||
			printf 'set mtu %s\n' "$mtu" >> "$dir/iplink"

		[ -s "$dir/iplink" ] ||
			rm -f -- "$dir/iplink"

		[ -z "$hostname" ] ||
			printf '%s\n' "$hostname" > "$dir/hostname"

		mask=
		if [ -n "$netmask" ]; then
			[ -z "${netmask##*[!0-9]*}" ] ||
				mask="$netmask"
			[ -n "${netmask##*.*.*.*}" ] ||
				mask=$(ipv4_mask2prefix "$netmask") ||
				fatal "unable to convert prefix to mask: $netmask"
		fi

		if [ -n "$ipaddr" ]; then
			get_version "$ipaddr" 4
			printf '%s\n' "$ipaddr${mask:+/$mask}${srv:+ peer $srv}" > "$dir/ipv${ip_version}address"
		fi

		if [ -n "$mask" ] && [ -n "$gw" ]; then
			get_version "$gw" 4
			printf 'default via %s\n' "$gw" > "$dir/ipv${ip_version}route"
		fi

		[ -z "$dns1" ] && [ -z "$dns2" ] ||
			printf 'nameserver %s\n' $dns1 $dns2 >> "$dir/resolv.conf"

		i=$(($i+1))
	done

	i=0
	while [ $i -lt ${ROUTE:-0} ]; do
		eval "route_to_var \"\$ROUTE$i\""

		dir="$net_confdir/ifaces/$interface"
		mkdir -p -- "$dir"

		get_version "$route_gw" 4
		printf '%s\n' "$route_mask${route_gw:+ via $route_gw}" >> "$dir/ipv${ip_version}route"

		i=$(($i+1))
	done
}

[ "$IP" = 0 ] && [ "$ROUTE" = 0 ] && [ "$NAMESERVER" = 0 ] && [ "$IFNAME" = 0 ] ||
	action_shell 'Generating network configuration:' configure
