#!/bin/bash
# info: update system IP
# options: NONE
#
# example: v-update-sys-ip
#          # Intended for internal usage
#
# This function scans configured IP in the system and register them with Hestia
# internal database. This call is intended for use on vps servers, where IP is
# set by hypervisor.

#----------------------------------------------------------#
#                Variables & Functions                     #
#----------------------------------------------------------#

# Includes
# shellcheck source=/etc/hestiacp/hestia.conf
source /etc/hestiacp/hestia.conf
# shellcheck source=/usr/local/hestia/func/main.sh
source $HESTIA/func/main.sh
# shellcheck source=/usr/local/hestia/func/ip.sh
source $HESTIA/func/ip.sh
# shellcheck source=/usr/local/hestia/func/domain.sh
source $HESTIA/func/domain.sh
# load config file
source_conf "$HESTIA/conf/hestia.conf"

#----------------------------------------------------------#
#                    Verifications                         #
#----------------------------------------------------------#

# Perform verification if read-only mode is enabled
check_hestia_demo_mode

#----------------------------------------------------------#
#                       Action                             #
#----------------------------------------------------------#

confd=$(get_conf_d_name "$WEB_SYSTEM")
pconfd=$(get_conf_d_name "$PROXY_SYSTEM")

# Listing system IP addresses
nics="$(ip -d -j link show | jq -r '.[] | if .link_type == "loopback" then empty else .ifname end')"

for nic in $nics; do
	nic_type="$(ip -d -j link show "$nic" | jq -r '.[].linkinfo.info_kind')"
	if [ "$nic_type" = "bridge" ]; then
		break
	fi
	nic_ipv4s="$(ip -4 -d -j addr show "$nic" | jq -r '.[] | select(length > 0) | .addr_info[] | if .scope == "global" then .local else empty end')"
	if [ -z "$ips" ]; then
		ips="$nic_ipv4s"
	else
		ips="$ips $nic_ipv4s"
	fi
done

v_ips="$(ls $HESTIA/data/ips/)"
ip_num="$(echo "$ips" | wc -w)"
v_ip_num="$(echo "$v_ips" | wc -w)"

# Checking primary IP change
if [ "$ip_num" -eq "1" ] && [ "$v_ip_num" -eq "1" ]; then
	if [ -n "$v_ips" ] && [ "$ips" != "$v_ips" ]; then
		new_ip="$ips"
		old_ip="$v_ips"
	fi
fi

# Updating configs
if [ -n "$old_ip" ]; then
	mv $HESTIA/data/ips/$old_ip $HESTIA/data/ips/$new_ip

	# Generating timestamp
	new_timestamp

	# Updating IP's values
	ip="$new_ip"
	interface="$(ip -d -j addr show | jq --arg IP "$ip" -r '.[] | if .addr_info[].local == $IP then .ifname else empty end')"
	prefixlen="$(ip -d -j addr show | jq --arg IP "$ip" -r '.[].addr_info[] | if .local == $IP then .prefixlen else empty end')"
	netmask="$(convert_cidr "$prefixlen")"
	update_ip_value '$INTERFACE' "$interface"
	update_ip_value '$NETMASK' "$netmask"
	update_ip_value '$TIME' "$time"
	update_ip_value '$DATE' "$date"

	# Updating PROXY
	if [ -n "$PROXY_SYSTEM" ]; then
		cd /etc/$PROXY_SYSTEM/$pconfd
		if [ -e "$old_ip.conf" ]; then
			mv $old_ip.conf $new_ip.conf
			sed -i "s/$old_ip/$new_ip/g" $new_ip.conf
		fi
	fi

	# Updating WEB
	if [ -n "$WEB_SYSTEM" ]; then
		cd /etc/$WEB_SYSTEM/$confd

		if [ -e "$old_ip.conf" ]; then
			mv $old_ip.conf $new_ip.conf
			sed -i "s/$old_ip/$new_ip/g" $new_ip.conf
		fi

		for user in $($BIN/v-list-sys-users plain); do
			sed -i "s/$old_ip/$new_ip/g" $HESTIA/data/users/$user/web.conf
			$BIN/v-rebuild-web-domains "$user" no
		done

		if [ -e "/etc/apache2/mods-available/remoteip.conf" ]; then
			sed -i "s/$old_ip/$new_ip/g" /etc/apache2/mods-available/remoteip.conf
		fi

		if [ -e "/etc/apache2/mods-enabled/rpaf.conf" ]; then
			sed -i "s/$old_ip/$new_ip/g" /etc/apache2/mods-enabled/rpaf.conf
		fi

		$BIN/v-restart-proxy
		$BIN/v-restart-web
	fi

	# Updating MAIL
	if [ -n "$IMAP_SYSTEM" ]; then
		for user in $($BIN/v-list-sys-users plain); do
			$BIN/v-rebuild-mail-domains "$user" no
		done
		$BIN/v-restart-mail
	fi

	# Updating DNS
	if [ -n "$DNS_SYSTEM" ]; then
		for user in $($BIN/v-list-sys-users plain); do
			sed -i "s/$old_ip/$new_ip/g" $HESTIA/data/users/$user/dns.conf
			sed -i "s/$old_ip/$new_ip/g" $HESTIA/data/users/$user/dns/*.conf
			$BIN/v-rebuild-dns-domains "$user" no
		done
		$BIN/v-restart-dns
	fi

	# Updating FTP
	if [ -n "$FTP_SYSTEM" ] && [ "$FTP_SYSTEM" = 'vsftpd' ]; then
		ftp_conf="$(find /etc/ -maxdepth 2 -name $FTP_SYSTEM.conf)"
		if [ -n "$ftp_conf" ]; then
			sed -i "s/$old_ip/$new_ip/g" "$ftp_conf"
			$BIN/v-restart-ftp
		fi
	fi

	# Updating firewall
	if [ -n "$FIREWALL_SYSTEM" ]; then
		sed -i "s/$old_ip/$new_ip/g" $HESTIA/data/firewall/*.conf
		$BIN/v-update-firewall
	fi
fi

# Adding system IP
for ip in $ips; do
	check_ip="$(ip addr list | grep -w "$ip")"
	if [ ! -e "$HESTIA/data/ips/$ip" ] && [ -n "$check_ip" ]; then
		interface="$(ip -d -j addr show | jq --arg IP "$ip" -r '.[] | if .addr_info[].local == $IP then .ifname else empty end')"
		prefixlen="$(ip -d -j addr show | jq --arg IP "$ip" -r '.[].addr_info[] | if .local == $IP then .prefixlen else empty end')"
		netmask="$(convert_cidr "$prefixlen")"
		$BIN/v-add-sys-ip "$ip" "$netmask" "$interface"
	elif [ -e "/etc/nginx/conf.d/$ip.conf" ]; then
		process_http2_directive "/etc/nginx/conf.d/$ip.conf"
	fi
done

# Updating NAT
if [ -e $HESTIA/conf/nopublickip ]; then
	ip="$(ls -t $HESTIA/data/ips/ | head -n1)"
	$BIN/v-change-sys-ip-nat "$ip" "$ip"
else
	pub_ipv4="$(curl -fsLm5 --retry 2 --ipv4 https://ip.hestiacp.com/)"
	if [ ! -e "$HESTIA/data/ips/$pub_ipv4" ]; then
		if [ -z "$(grep -R "$pub_ipv4" $HESTIA/data/ips/)" ]; then
			ip="$(ls -t $HESTIA/data/ips/ | head -n1)"
			$BIN/v-change-sys-ip-nat "$ip" "$pub_ipv4"
		fi
	fi
fi

# Updating IP usage counters
$BIN/v-update-sys-ip-counters

#----------------------------------------------------------#
#                       Hestia                             #
#----------------------------------------------------------#

exit