#!/usr/bin/env atf-sh

. "$(atf_get_srcdir)/test_env.sh"
init_tests \
	setup_interfaces_usage \
	setup_interfaces_none \
	setup_interfaces_interactive_dhcp \
	setup_interfaces_interactive_none \
	setup_interfaces_interactive_vlan \
	setup_interfaces_interactive_vlan_ng \
	setup_interfaces_interactive_vlan0_ng \
	setup_interfaces_interactive_br0 \
	setup_interfaces_interactive_bond0 \
	setup_interfaces_interactive_wlan0_psk \
	setup_interfaces_interactive_wlan0_psk_by_index \
	setup_interfaces_interactive_wlan0_open \
	setup_interfaces_interactive_ssid_list \
	setup_interfaces_auto_single \
	setup_interfaces_auto_first \
	setup_interfaces_auto_up \
	setup_interfaces_auto_none \
	setup_interfaces_auto_restart \
	setup_interfaces_import_wifi_config \
	setup_interfaces_import_wifi_config_missing \


setup_interfaces_usage_body() {
	test_usage setup-interfaces
}

create_fake_ifaces() {
	local n=1
	for i; do
		mkdir -p "sys/class/net/$i"
		echo $n > "sys/class/net/$i/ifindex"
		echo down > "sys/class/net/$i/operstate"
		n=$((n+1))
	done
}

setup_interfaces_none_body() {
	init_env
	create_fake_ifaces lo eth0
	atf_check -s exit:0 \
		setup-interfaces none
	if [ -f etc/network/interfaces ]; then
		atf_fail "etc/network/interfaces should not be created"
	fi
}

setup_interfaces_interactive_dhcp_body() {
	init_env
	create_fake_ifaces lo eth0 docker0
	(
		# Which one do you want to initialize? (or '?' or 'done') [eth0]
		echo "eth0"
		# IPv4 address for eth0? (or 'dhcp', 'none', '?') [dhcp]
		echo "dhcp"
		# IPv6 address for eth0? (or 'auto', 'dhcp', 'none', '?') [auto]
		echo "dhcp"
		# Do you want to do any manual network configuration? (y/n) [n]
		echo "n"
	)>answers
	atf_check -s exit:0 \
		-o match:"Available interfaces are: eth0[^ ]" \
		setup-interfaces <answers
}

setup_interfaces_interactive_none_body() {
	init_env
	create_fake_ifaces lo eth0
	(
		# Which one do you want to initialize? (or '?' or 'done') [eth0]
		echo none
	)>answers
	atf_check -s exit:0 \
		-o match:"Available interfaces are: eth0" \
		setup-interfaces <answers
	if [ -f etc/network/interfaces ]; then
		atf_fail "etc/network/interfaces should not be created"
	fi
}

setup_interfaces_interactive_vlan_body() {
	init_env
	create_fake_ifaces lo eth0
	(
		# Which one do you want to initialize? (or '?' or 'done') [eth0]
		echo "eth0.5"
		# IPv4 address for eth0.5? (or 'dhcp', 'none', '?') [dhcp]
		echo "dhcp"
		# IPv6 address for eth0.5? (or 'auto', 'dhcp', 'none', '?') [auto]
		echo "dhcp"
		# Which one do you want to initialize? (or '?' or 'done') [eth0]
		echo "done"
		# Do you want to do any manual network configuration? (y/n) [n]
		echo "n"
	)>answers
	atf_check -s exit:0 \
		-o match:"apk add.*vlan" \
		setup-interfaces <answers
}

setup_interfaces_interactive_vlan_ng_body() {
	init_env
	create_fake_ifaces lo eth0

	mkdir -p usr/libexec/ifupdown-ng
	touch usr/libexec/ifupdown-ng/link

	(
		# Which one do you want to initialize? (or '?' or 'done') [eth0]
		echo "eth0.5"
		# IPv4 address for eth0.5? (or 'dhcp', 'none', '?') [dhcp]
		echo "dhcp"
		# IPv6 address for eth0.5? (or 'auto', 'dhcp', 'none', '?') [auto]
		echo "dhcp"
		# Which one do you want to initialize? (or '?' or 'done') [eth0]
		echo "done"
		# Do you want to do any manual network configuration? (y/n) [n]
		echo "n"
	)>answers
	atf_check -s exit:0 \
		-o not-match:"apk add.*vlan" \
		setup-interfaces <answers
}

setup_interfaces_interactive_vlan0_ng_body() {
	init_env
	create_fake_ifaces lo eth0

	mkdir -p usr/libexec/ifupdown-ng
	touch usr/libexec/ifupdown-ng/link

	(
		# Which one do you want to initialize? (or '?' or 'done') [eth0]
		echo "vlan0"
		# Which one do you want use for vlan0? (or 'done') [eth0]
		echo "eth0"
		# IPv4 address for vlan0? (or 'dhcp', 'none', '?') [dhcp]
		echo "dhcp"
		# IPv6 address for vlan0? (or 'auto', 'dhcp', 'none', '?') [auto]
		echo "dhcp"
		# Which one do you want to initialize? (or '?' or 'done') [eth0]
		echo "done"
		# Do you want to do any manual network configuration? (y/n) [n]
		echo "n"
	)>answers
	atf_check -s exit:0 \
		-o match:"Available raw devices are: eth0" \
		-o not-match:"apk add.*vlan" \
		setup-interfaces <answers
}

setup_interfaces_interactive_br0_body() {
	init_env
	create_fake_ifaces lo eth0

	mkdir -p usr/libexec/ifupdown-ng
	touch usr/libexec/ifupdown-ng/bridge

	(
		# Which one do you want to initialize? (or '?' or 'done') [eth0]
		echo "br0"
		# Which port(s) do you want add to bridge br0? (or 'done') [eth0]
		echo "eth0"
		# IPv4 address for vlan0? (or 'dhcp', 'none', '?') [dhcp]
		echo "dhcp"
		# IPv6 address for vlan0? (or 'auto', 'dhcp', 'none', '?') [auto]
		echo "dhcp"
		# Which one do you want to initialize? (or '?' or 'done') [eth0]
		echo "done"
		# Do you want to do any manual network configuration? (y/n) [n]
		echo "n"
	)>answers
	atf_check -s exit:0 \
		-o match:"Available bridge ports are: eth0" \
		-o match:"apk add.*bridge" \
		setup-interfaces <answers
}

setup_interfaces_interactive_bond0_body() {
	init_env
	create_fake_ifaces lo eth0

	mkdir -p usr/libexec/ifupdown-ng
	touch usr/libexec/ifupdown-ng/bond

	(
		# Which one do you want to initialize? (or '?' or 'done') [eth0]
		echo "bond0"
		# Which slave(s) do you want add to bond0? (or 'done') [eth0]
		echo "eth0"
		# IPv4 address for bond0? (or 'dhcp', 'none', '?') [dhcp]
		echo "dhcp"
		# IPv6 address for bond0? (or 'auto', 'dhcp', 'none', '?') [auto]
		echo "dhcp"
		# Do you want to do any manual network configuration? (y/n) [n]
		echo "n"
	)>answers
	atf_check -s exit:0 \
		-o match:"Available interfaces are: eth0" \
		-o match:"apk add.*bonding" \
		setup-interfaces <answers
}

setup_interfaces_interactive_wlan0_psk_body() {
	init_env
	create_fake_ifaces lo eth0 wlan2
	mkdir -p sys/class/net/wlan2/phy80211

	(
		# Which one do you want to initialize? (or '?' or 'done') [eth0]
		echo "wlan2"
		# Type the wireless network name to connect to:
		echo "Telenor0366rar"
		# Type the "Telenor0366rar" network Pre-Shared Key (will not echo):
		echo "0123456789"
		# IPv4 address for wlan0? (or 'dhcp', 'none', '?') [dhcp]
		echo "dhcp"
		# IPv6 address for wlan0? (or 'auto', 'dhcp', 'none', '?') [auto]
		echo "dhcp"
		# Do you want to do any manual network configuration? (y/n) [n]
		echo "n"
	)>answers
	atf_check -s exit:0 \
		-o match:"Available interfaces are: eth0 wlan2" \
		-o match:"Lynx2C0CEA_5G" \
		-o match:"Get-B3ED64" \
		-o not-match:"x00" \
		-o match:"Type the \"Telenor0366rar\" network Pre-Shared Key" \
		-o match:"IPv4 address for wlan2" \
		setup-interfaces <answers
}

setup_interfaces_interactive_wlan0_psk_by_index_body() {
	init_env
	create_fake_ifaces lo eth0 wlan3
	mkdir -p sys/class/net/wlan3/phy80211

	(
		# Which one do you want to initialize? (or '?' or 'done') [eth0]
		echo "wlan3"
		# 1) Get-B3ED64
		# 2) Lynx2C0CEA
		# 3) Lynx2C0CEA_5G
		# 4) Telenor0366rar-5GHz
		# 5) Telenor0366rar
		# 6) kano1
		# Type the wireless network name to connect to:
		echo "5"
		# Type the "Telenor0366rar" network Pre-Shared Key (will not echo):
		echo "0123456789"
		# IPv4 address for wlan0? (or 'dhcp', 'none', '?') [dhcp]
		echo "dhcp"
		# IPv6 address for wlan0? (or 'auto', 'dhcp', 'none', '?') [auto]
		echo "dhcp"
		# Do you want to do any manual network configuration? (y/n) [n]
		echo "n"
	)>answers
	atf_check -s exit:0 \
		-o match:"Available interfaces are: eth0 wlan3" \
		-o match:"Lynx2C0CEA_5G" \
		-o match:"Get-B3ED64" \
		-o not-match:"x00" \
		-o match:"Type the \"Telenor0366rar\" network Pre-Shared Key" \
		-o match:"IPv4 address for wlan3" \
		setup-interfaces <answers
}

setup_interfaces_interactive_wlan0_open_body() {
	init_env
	create_fake_ifaces lo eth0 wlan0
	mkdir -p sys/class/net/wlan0/phy80211

	(
		# Which one do you want to initialize? (or '?' or 'done') [eth0]
		echo "wlan0"
		# Type the wireless network name to connect to:
		echo "Lynx2C0CEA_5G"
		# IPv4 address for wlan0? (or 'dhcp', 'none', '?') [dhcp]
		echo "dhcp"
		# IPv6 address for wlan0? (or 'auto', 'dhcp', 'none', '?') [auto]
		echo "dhcp"
		# Do you want to do any manual network configuration? (y/n) [n]
		echo "n"
	)>answers
	atf_check -s exit:0 \
		-o match:"Available interfaces are: eth0 wlan0" \
		-o match:"Telenor0366rar" \
		-o match:"Get-B3ED64" \
		-o not-match:"x00" \
		-o not-match:"Type the \"Lynx2C0CEA_5g\" network Pre-Shared Key" \
		-o match:"IPv4 address for wlan0" \
		setup-interfaces <answers
}

setup_interfaces_interactive_ssid_list_body() {
	init_env
	create_fake_ifaces lo eth0 wlan0
	mkdir -p sys/class/net/wlan0/phy80211

	(
		# Which one do you want to initialize? (or '?' or 'done') [eth0]
		echo "wlan0"
		# Type the wireless network name to connect to:
		echo "kano1"
		# IPv4 address for wlan0? (or 'dhcp', 'none', '?') [dhcp]
		echo "dhcp"
		# IPv6 address for wlan0? (or 'auto', 'dhcp', 'none', '?') [auto]
		echo "dhcp"
		# Do you want to do any manual network configuration? (y/n) [n]
		echo "n"
	)>answers

	atf_check -s exit:0 \
		-o match:"Available interfaces are: eth0 wlan0" \
		-o match:"kano1" \
		-o match:"Type the \"kano1\" network Pre-Shared Key" \
		setup-interfaces <answers
}

setup_interfaces_auto_single_body() {
	init_env
	create_fake_ifaces lo eth0
	atf_check -s exit:0 \
		-o match:"ip link set dev eth0 up" \
		-o not-match:"ip link set dev eth0 down" \
		setup-interfaces -a

	atf_check \
		-o match:"auto lo" \
		-o match:"iface lo inet loopback" \
		-o match:"iface lo inet6 loopback" \
		-o match:"auto eth0" \
		-o match:"iface eth0 inet dhcp" \
		-o match:"iface eth0 inet6 auto" \
		cat etc/network/interfaces
}

setup_interfaces_auto_first_body() {
	init_env
	create_fake_ifaces lo eth0 eth1
	atf_check -s exit:0 \
		-o match:"ip link set dev eth0 up" \
		-o match:"ip link set dev eth1 up" \
		-o match:"ip link set dev eth1 down" \
		setup-interfaces -a

	# use first interface if all are down
	atf_check \
		-o match:"auto lo" \
		-o match:"iface lo inet loopback" \
		-o match:"iface lo inet6 loopback" \
		-o match:"auto eth0" \
		-o match:"iface eth0 inet dhcp" \
		-o match:"iface eth0 inet6 auto" \
		cat etc/network/interfaces
}

setup_interfaces_auto_up_body() {
	init_env
	create_fake_ifaces lo eth0 eth1 eth2 eth3
	echo up > sys/class/net/eth1/operstate
	echo up > sys/class/net/eth2/operstate
	atf_check -s exit:0 \
		-o match:"ip link set dev eth0 up" \
		-o match:"ip link set dev eth1 up" \
		-o match:"ip link set dev eth2 up" \
		-o match:"ip link set dev eth3 up" \
		-o match:"ip link set dev eth3 down" \
		-o match:"ip link set dev eth2 down" \
		-o not-match:"ip link set dev eth1 down" \
		-o match:"ip link set dev eth0 down" \
		setup-interfaces -a

	# use first interface that is up
	atf_check \
		-o match:"auto lo" \
		-o match:"iface lo inet loopback" \
		-o match:"iface lo inet6 loopback" \
		-o match:"auto eth1" \
		-o match:"iface eth1 inet dhcp" \
		-o match:"iface eth1 inet6 auto" \
		cat etc/network/interfaces
}

setup_interfaces_auto_none_body() {
	init_env
	create_fake_ifaces lo
	atf_check -s exit:0 \
		setup-interfaces -a

	# do not setup dhcp on lo
	if [ -e etc/network/interfaces ]; then
		atf_fail "etc/network/interfaces should not be created"
	fi
}

setup_interfaces_auto_restart_body() {
	init_env
	create_fake_ifaces lo eth0
	atf_check -s exit:0 \
		-o match:"ip link set dev eth0 up" \
		setup-interfaces -a -r
	atf_check -o match:"status: started" rc-service networking status
}

setup_interfaces_import_wifi_config_body() {
	init_env
	cat > interfaces <<-EOF
		auto lo
		iface lo inet loopback

		auto wlan0
		iface wlan0 inet dhcp
	EOF
	cat > wpa_supplicant.conf <<-EOF
		ctrl_interface=/run/wpa_supplicant
		network={
			ssid="example"
			psk="secret"
		}
	EOF

	atf_check -s exit:0 \
		-o match:"apk add.*wpa_supplicant" \
		setup-interfaces -w wpa_supplicant.conf -i < interfaces

	atf_check -o match:"auto wlan0" cat etc/network/interfaces
	atf_check -o match:'ssid="example"' \
		cat etc/wpa_supplicant/wpa_supplicant.conf
	if ! [ -L etc/runlevels/boot/wpa_supplicant ]; then
		atf_fail "wpa_supplicant should be enabled at boot"
	fi
	if [ -e run/started/wpa_supplicant ]; then
		atf_fail "wpa_supplicant should not be started"
	fi
}

setup_interfaces_import_wifi_config_missing_body() {
	init_env
	cat > interfaces <<-EOF
		auto lo
		iface lo inet loopback
	EOF

	atf_check -s not-exit:0 \
		-e match:"missing.conf: wpa_supplicant config not found" \
		setup-interfaces -w missing.conf -i < interfaces
}
