#!/bin/bash -efu

. shell-config

stage1_network_dir=/run/stage1/network/ifaces
hostname_cfg=/etc/hostname
netcfg="/etc/sysconfig/network"
etcnet_dir="/etc/net/ifaces"
systemd_network_dir="/etc/systemd/network"

link_yes() {
	local link
	link="$(ethtool "$1" 2>/dev/null | awk '/Link detected:/ {print $3}')"
	[ "$link" = yes ] || return 1
	return 0
}

list_eth() {
	local sysdir=/sys/class/net
	local iface type
	[ -d "$sysdir" ] || return 1
	find "$sysdir" -mindepth 1 -maxdepth 1 -name en* -xtype d -printf '%f\n' |
		while read iface; do
			read type < "$sysdir/$iface/type"
			[ "$type" = 1 ] && echo "$iface" # ethernet
		done
}

setup_etcnet() {
	[ -n "$1" ] || return 1
	local ifacedir="$etcnet_dir/$1"
	[ -d "$etcnet_dir" ] || return 0
	[ ! -d "$ifacedir" ] || return 0
	echo -n "$1 "
	# NB: 3 seconds means STP ports will stay down => unconfigured
	mkdir -p "$ifacedir"
	# NetworkManager(etcnet)
	[ "$NM_CONTROLLED" != yes ] || touch $ifacedir/ipv4address
	cat>"$ifacedir/options"<<EOF
TYPE=eth
CONFIG_WIRELESS=no
BOOTPROTO=$ETCNET_BOOTPROTO
SYSTEMD_BOOTPROTO=$SYSTEMD_BOOTPROTO
CONFIG_IPV4=yes
DISABLED=$ETCNET_DISABLED
NM_CONTROLLED=$NM_CONTROLLED
SYSTEMD_CONTROLLED=$SYSTEMD_CONTROLLED
ONBOOT=yes
EOF
	# Copy network settings from stage1
	if [ -s "$stage1_network_dir"/"$i"/ipv4address ]; then
		[ ! -s "$stage1_network_dir"/"$1"/ipv4address ] ||
			cp "$stage1_network_dir"/"$1"/ipv4address "$ifacedir"/
		[ ! -s "$stage1_network_dir"/"$1"/ipv4route ] ||
			cp "$stage1_network_dir"/"$1"/ipv4route "$ifacedir"/
		[ ! -s "$stage1_network_dir"/"$1"/resolv.conf ] ||
			cp "$stage1_network_dir"/"$1"/resolv.conf "$ifacedir"/
		# setup static interface
		shell_config_set "$ifacedir/options" BOOTPROTO static
		shell_config_set "$ifacedir/options" SYSTEMD_BOOTPROTO static
		shell_config_set "$ifacedir/options" SYSTEMD_CONTROLLED no
	elif [ "$ETCNET_DISABLED" = no ] && [ -z "$LINK_YES" ]; then
		# setup etcnet interface as static, when etcnet manage and not link detected
		shell_config_set "$ifacedir/options" BOOTPROTO static
		shell_config_set "$ifacedir/options" SYSTEMD_BOOTPROTO static
	elif [ "$ETCNET_BOOTPROTO" = dhcp ]; then
		# set limit dhcp timeout
		echo "DHCP_TIMEOUT=7" >> "$ifacedir/options"
	fi
}

setup_networkd() {
	[ -n "$1" ] || return 1
	[ "$SYSTEMD_CONTROLLED" = yes ] || return 0
	[ ! -s "$stage1_network_dir"/"$i"/ipv4address ] || return 0
	local iface_conf
	iface_conf="$systemd_network_dir/$1.network"
	[ ! -s "$iface_conf" ] || return 0
	cat>"$iface_conf"<<EOF
[Match]
	Name = $1
[Network]
	IPv6AcceptRA = false
	DHCP = ipv4
	LinkLocalAddressing = no
[DHCPv4]
	UseDomains = true
	UseDNS = yes
EOF
}

# setup hostname from stage1 network settings
stage1_hostname_cfg="$(find "$stage1_network_dir" -type f -name hostname | head -n1)"
[ -z "$stage1_hostname_cfg" ] ||
	HOSTNAME="$(head -n1 "$stage1_hostname_cfg")"
if [ -f "$netcfg" ]; then
	shell_config_set "$netcfg" NETWORKING yes
	[ -z "$HOSTNAME" ] || shell_config_set "$netcfg" HOSTNAME "$HOSTNAME"
fi
	if [ -f "$hostname_cfg" ]; then
	[ -z "$HOSTNAME" ] || echo "$HOSTNAME" > "$hostname_cfg"
fi
if which NetworkManager >/dev/null 2>&1; then
	# NetworkManager
	ETCNET_BOOTPROTO=dhcp
	SYSTEMD_BOOTPROTO=dhcp4
	ETCNET_DISABLED=yes
	NM_CONTROLLED=yes
	SYSTEMD_CONTROLLED=no
elif which networkctl >/dev/null 2>&1; then
	# systemd-networkd
	ETCNET_BOOTPROTO=dhcp
	SYSTEMD_BOOTPROTO=dhcp4
	ETCNET_DISABLED=yes
	NM_CONTROLLED=no
	SYSTEMD_CONTROLLED=yes
else
	# etcnet
	if [ -x /sbin/dhcpcd -o -x /sbin/dhclient ]; then
		ETCNET_BOOTPROTO=dhcp
		SYSTEMD_BOOTPROTO=dhcp4
	else
		ETCNET_BOOTPROTO=static
		SYSTEMD_BOOTPROTO=static
	fi
	ETCNET_DISABLED=no
	NM_CONTROLLED=no
	SYSTEMD_CONTROLLED=no
fi
ifaces="$(list_eth)"
if [ -n "$ifaces" ]; then
	for i in $ifaces; do
		LINK_YES=
		LINK_ALREADY_YES=
		! link_yes "$i" || LINK_ALREADY_YES=yes
		LINK_YES="$LINK_ALREADY_YES"
		# up the interface if link is not already
		[ -n "$LINK_ALREADY_YES" ] || ip link set "$i" up ||:
		[ -n "$LINK_YES" ] || ! link_yes "$i" || LINK_YES=yes
		[ -n "$LINK_ALREADY_YES" ] || ! link_yes "$i" || LINK_YES=yes
		# down the interface which were up here
		[ -n "$LINK_ALREADY_YES" ] || ip link set "$i" down ||:
		setup_etcnet "$i"
		[ -z "$LINK_YES" ] || setup_networkd "$i"
	done
fi
