#!/bin/sh

############ common network helpers

PATH=/usr/lib/alterator-net-common:$PATH

ifrestart()
{
    echo "Restarting $i" >&2
    ifdown "$1" && ifup "$1"
}

condifup()
{
    ifcheckup "$1" || (ifup "$1" && echo "Up $1" >&2)
}

dhcp_foreach()
{
	local i
	for i in /etc/net/ifaces/*;do
		i="${i##*/}"
		[ "$i" != "unknown" -a "$i" != "default" ] || continue

		ifcheckdhcp "$i" && "$1" "$i"
	done >/dev/null
}


############ main config files

netconfig="/etc/sysconfig/network"
resolv_conf="/etc/resolv.conf"
etc_hosts="/etc/hosts"
hostnameconfig="/etc/HOSTNAME"

############ helpers: shell config

shell_add_or_subst()
{
	local name="$1" && shift
	local value="$1" && shift
	local file="$1" && shift

	[ -f "$file" ] || touch "$file"
	if grep -qs "^$name" "$file"; then
		/bin/sed -r -i "s,^$name.*,$name$value," -- "$file"
		return 0
	fi
	printf %s\\n "$name$value" >> "$file"
}

shell_get()
{
	local name="$1" && shift
	local file="$1" && shift

	[ -f "$file" ] &&
	grep -qs "^$name=" "$file" &&
	grep "^$name=" "$file"|sed "s,^$name=,,"
}

############ hostname

local_hostname()
{
	shell_get "HOSTNAME" "$netconfig"
}

dhcp_hostname()
{
	f=$(grep -l "HOSTNAME=" /etc/dhcpc/*.info /var/lib/dhcpcd/*.info 2>/dev/null)
	[ -n "$f" ] && shell_get "HOSTNAME" "$f"|sed "s,',,g"
}

resolve_hostname()
{
    grep -qs "^nameserver" "$resolv_conf" &&
    for i in $(/sbin/ip addr show |
 	   	sed -ne 's,^[[:space:]]*inet[[:space:]]\+\([^/]\+\).*,\1,p'|
		grep -v '^127\.') ;do
	/usr/bin/resolve -t 2 -s "$i" && return 0
    done
    return 1
}

add_hosts()
{
	local host_name="$1" && shift
	grep -qs "^[^#]*\<$host_name\>" "$etc_hosts" && return 0
	if grep -qs "^127.0.0.1" "$etc_hosts"; then
		sed -r -e "s,^127\.0\.0\.1[[:space:]].*,127.0.0.1	$host_name ${host_name%%.*} localhost.localdomain localhost," -i "$etc_hosts"
		return 0
	fi
	printf '127.0.0.1\t%s %s\n' "$host_name" "${host_name%%.*} localhost.localdomain localhost" >> "$etc_hosts"
}

read_hostname()
{
	local_hostname || resolve_hostname || echo "localhost.localdomain"
}

write_hostname()
{
	local value="$1" && shift
	shell_add_or_subst "HOSTNAME=" "$value" "$netconfig"
	shell_add_or_subst "DOMAINNAME=" "${value#*.}" "$netconfig"
	printf %s\\n "$value" >"$hostnameconfig"
	hostname "$value"
	domainname "${value#*.}"
	add_hosts "$value"	
}

############ dns

read_dns()
{
	[ -f "$resolv_conf" ] &&
	grep "^nameserver " "$resolv_conf"|sed s,nameserver[[:space:]]*,,
}


write_dns()
{
	local values="$1" && shift
	[ -f "$resolv_conf" ] || touch "$resolv_conf"
	sed -i -r '/^nameserver/ d' "$resolv_conf"
	for i in $values ;
	do
		printf "nameserver %s\n" "$i" >>"$resolv_conf"
	done
}

############ search

read_search()
{
	[ -f "$resolv_conf" ] &&
	grep "^search " "$resolv_conf"|sed s,search[[:space:]]*,,|tr ' ' '\n'
}

write_search()
{
	local value="$(echo "$1"|grep -v '^$'|sed -r 's,^[[:space:]]*([^[:space:]]+)[[:space:]]*,\1,'|tr '\n' ' ')"
	shell_add_or_subst "search " "$value" "$resolv_conf"
}

############ dhcp args
read_dhcp()
{
	local f
	for f in /etc/net/ifaces/*; do
		f=${f##/etc/net/ifaces/}
		[ "$f" != "unknown" ] && [ "$f" != "default" ] || continue

		ifcheckdhcp "$f" && return 0
	done
	return 1
}


read_dhcp_arg()
{
	local arg="$1" && shift
	grep -wqs  -- "-$arg" 
}

write_dhcp_arg()
{
	local f
	local arg="$1" && shift
	local value="$1" && shift

	for f in /etc/net/ifaces/*; do
		mf=${f##/etc/net/ifaces/}
		[ "$mf" != "unknown" ] && [ "$mf" != "default" ] || continue

		ifcheckdhcp "$mf" >/dev/null &&
		(args="$(ifvar "$mf" DHCP_ARGS | sed -r "s,(^|.*[[:space:]])-$arg([[:space:]]*.*|$),\1\2," | sed -r 's,^[[:space:]]*(.*)[[:space:]]+$,\1,')" #"
	    	 sed -i '/^DHCP_ARGS=.*/d' "$f/options"
		 if [ "$value" = "yes" ];then
			printf "DHCP_ARGS=\"%s -$arg\"\n" "$args" >> "$f/options"
		 else
			[ -z "$args" ] || printf 'DHCP_ARGS="%s"\n' "$args" >> "$f/options"
		 fi
		)
	done
}

_()
{
LANG="${in_language%%;*}.utf8" gettext "alterator-net-general" "$1"
}

. /usr/share/alterator/build/backend3.sh


#initial actions
ifup lo
dhcp_foreach "condifup"

on_message()
{
	case "$in_action" in
		constraints)
			echo '('
			echo 'has_dhcp (exclude (#f hostname_auto) exclude (#f dns_auto))'
			printf 'hostname_auto (exclude (#t hostname) default #f label "%s")\n' \
				"`_ "Get hostname from DHCP"`"
			printf 'dns_auto (exclude (#t dns) exclude (#t search) default #f label "%s")\n' \
				"`_ "Get resolver configuration from DHCP"`"
			printf 'hostname (required #t hostname #t label "%s" default "localhost.localdomain")\n' \
				"`_ "Hostname"`"
			printf 'search (hostname #t label "%s")\n' \
				"`_ "Search Domains"`"
			printf 'dns (ipv4-address #t label "%s")' \
				"`_ "Domain Name Servers (DNS)"`"
			echo ')'
			;;
		read) 
			local dns_dhcp=
			local hostname_dhcp=
			local dhcp=
 			if args="$(read_dhcp)"; then
				dhcp="yes"
				echo "$args"|read_dhcp_arg "H" && hostname_dhcp="yes"
				echo "$args"|read_dhcp_arg "R" || dns_dhcp="yes"
			fi
			local hname=
			[ "$hostname_dhcp" = "yes" ] && hname="$(dhcp_hostname)"
			[ -z "$hname" ] && hname="$(read_hostname)"

			echo "("
			printf "hostname \"%s\"\n" "$hname"
			printf "dns \"%s\"\n" "$(read_dns)"
			printf "search \"%s\"\n" "$(read_search)"
	
			printf "has_dhcp %s\n"  $([ "$dhcp" = "yes" ] && echo "#t" || echo "#f")
			printf "dns_auto %s\n"  $([ "$dns_dhcp" = "yes" ] && echo "#t" || echo "#f")
			printf "hostname_auto %s\n" $([ "$hostname_dhcp" = "yes" ] && echo "#t" || echo "#f")
			echo ")"
		;;
		write)
			[ -n "$in_dns_auto" ] && 
				write_dhcp_arg "R" $([ "$in_dns_auto" = "#t" ] && echo "no" || echo "yes")
			[ -n "$in_hostname_auto" ] && 
				write_dhcp_arg "H" $([ "$in_hostname_auto" = "#t" ] && echo "yes" || echo "no")

			#upgrade to new dhcpcd
			[ "$in_hostname_auto" = '#f' ] && 
				write_dhcp_arg "D" "no"

			[ -n "$in_hostname" ] &&
				if args="$(read_dhcp)"; then
					echo "$args"|read_dhcp_arg "H" || write_hostname "$in_hostname"
				else
					write_hostname "$in_hostname"
				fi
			[ -n "$in_dns" ] &&
				if args="$(read_dhcp)"; then
					echo "$args"|read_dhcp_arg "R" && write_dns "$in_dns"
				else
					write_dns "$in_dns"
				fi
			[ -n "$in_search" ] &&
				if args="$(read_dhcp)"; then
					echo "$args"|read_dhcp_arg "R" && write_search "$in_search"
				else
					write_search "$in_search"
				fi
			[ "$in_restart" = "#f" ] || dhcp_foreach "ifrestart"
			/sbin/update_chrooted conf >&2 || :
		    echo '()'
		    ;;
		*)
		    echo '#f'
		    ;;
	esac
}

message_loop
