#!/bin/sh
. /usr/share/libubox/jshn.sh
. /lib/functions/network.sh
_checkpid(){
	#Check the PID and prohibit repeated operation.
	pid=`echo $$`
	pname=`echo $0`
	mypidfile=/tmp/wsdwan.pid
	if test -f "$mypidfile";then
		expid=`cat $mypidfile`
		if grep $pname /proc/`cat $mypidfile`/cmdline > /dev/null 2>&1 ;then
			echo "The process $pname is already exists ! pid:$expid."
			exit 0
		fi		
	fi
	echo $pid > $mypidfile
}

_get_uuid(){
	#Get the unique UUID code of the device.
	uci get wsdwan.config.uuid > /dev/null 2>&1
	if [ "$?" != "0" ];then
		dmidecode > /dev/null 2>&1
		if [ "$?" = "0" ];then
			md5=`dmidecode | md5sum | awk '{print $1}'`
			uuid=`echo ${md5:0:8}-${md5:8:4}-${md5:12:4}-${md5:16:4}-${md5:0-12}`
        else
			uuid=`cat /proc/sys/kernel/random/uuid`  
        fi
		uci set wsdwan.config.uuid=$uuid
		uci commit wsdwan       
	else
		uuid=`uci get wsdwan.config.uuid`
		uci commit wsdwan
	fi
	echo uuid is $uuid
}

_getinfo(){
	#check wsdwan uci config
	touch /etc/config/wsdwan
	uci get  wsdwan.config > /dev/null 2>&1
	if [ "$?" != "0" ];then
		 uci set wsdwan.config=config
		 uci commit wsdwan
	fi
	#check quagga install
	if opkg list-installed|grep quagga > /dev/null 2>&1;then
		quagga=1
	else
		quagga=0
	fi
	#check dnsmasq with chnroute patch
	if dnsmasq --help|grep chnroute > /dev/null 2>&1;then
		dnsmasq=1
	else
		dnsmasq=0
	fi
	#Initialize running dnsmasq
	grep -r "chnroutes-file" /etc/dnsmasq.conf > /dev/null 2>&1
	if [ "$?" = "0" ];then
		echo "" > /etc/dnsmasq.conf
		/etc/init.d/dnsmasq restart> /dev/null 2>&1
	else
		ps|grep `cat /var/run/dnsmasq/*.pid`|grep -v grep > /dev/null 2>&1
		if [ "$?" != "0" ];then
			echo "" > /etc/dnsmasq.conf
			/etc/init.d/dnsmasq restart> /dev/null 2>&1
		fi
	fi
}

_checklicense(){
	uci get wsdwan.config.license >/dev/null 2>&1
	if [ "$?" = "0" ];then
		license=`uci get wsdwan.config.license`
		echo License is $license
	else
		echo "No License found."
		break
	fi
	uci get wsdwan.config.apitoken >/dev/null 2>&1
	if [ "$?" = "0" ];then
		apitoken=`uci get wsdwan.config.apitoken`
		echo APItoken is $apitoken
	else
		echo "No APItoken found."
		break
	fi
	if [[ -n "$license" ]] && [[ -n "$apitoken" ]];then
		license_info=$(curl -L -s -X GET -H "Authorization: Bearer $apitoken" -H 'X-Requested-With: XMLHttpRequest' -H 'Content-Type: application/json' "https://www.wsdwan.com/api/v1/licenses/$license")
		echo $license_info;
		json_load "$license_info"
		json_select nodes_info
			json_get_keys keys
			for k in $keys; do
				echo json_select $k
				json_select $k
					json_get_var nodename nodename
					json_get_var country country
					json_get_var port port
					json_get_var authgroup authgroup
					echo nodename $nodename
					echo port $port
					echo authgroup $authgroup
					uci show wsdwan|grep country|grep $country > /dev/null 2>&1
					if [ "$?" = "0" ];then
						nodeid=`uci show wsdwan|grep country|grep $country|awk -F "." '{print $2}'`
						uci set wsdwan.$nodeid.country=$country
						uci set wsdwan.$nodeid.nodename=$nodename
						uci set wsdwan.$nodeid.port=$port
						uci set wsdwan.$nodeid.authgroup=$authgroup
						uci commit wsdwan

					else
						nodeid=`uci add wsdwan node`
						uci set wsdwan.$nodeid.country=$country
						uci set wsdwan.$nodeid.nodename=$nodename
						uci set wsdwan.$nodeid.port=$port
						uci set wsdwan.$nodeid.authgroup=$authgroup
						uci commit wsdwan
					fi
				json_select ..
			done
		json_select ..

		json_select license_info
				json_get_var username username
				json_get_var password value
				json_get_var framedipaddress framedipaddress
				local_subnet=`echo $framedipaddress|awk -F "." '{print $1"."$2"."$3".0/24"}'`
				uci set wsdwan.config.subnet=$local_subnet
				uci set wsdwan.config.framedipaddress=$framedipaddress
				uci commit wsdwan
				echo username $username
				echo password $password
				echo framedipaddress $framedipaddress
				echo local_subnet $local_subnet
		json_select ..
	fi
}

_checkdnsmasq(){
	if [ "$dnsmasq" = "1" ];then
	_pre_init
cat>/tmp/dnsmasq.tmp<<EOF
no-resolv
all-servers
server=${NET_DNS%% *},0
server=1.1.1.1,1
chnroutes-file=/etc/chnroute

EOF
		dnsconfmd5=`md5sum /tmp/dnsmasq.tmp|awk '{print $1}'`
		dnsmasqmd5=`md5sum /etc/dnsmasq.conf|awk '{print $1}'`
		if [ "$dnsconfmd5" != "$dnsmasqmd5" ];then
			cp /tmp/dnsmasq.tmp /etc/dnsmasq.conf
			/etc/init.d/dnsmasq restart> /dev/null 2>&1
		fi
	else
		grep -r "chnroutes-file" /etc/dnsmasq.conf > /dev/null 2>&1
		if [ "$?" = "0" ];then
			echo "" > /etc/dnsmasq.conf
			/etc/init.d/dnsmasq restart> /dev/null 2>&1
		fi
	fi
	
}

_checkroute(){
	routenums=`wc -l /etc/chnroute|awk '{print $1}'`
	uci get wsdwan.config.selectroute > /dev/null 2>&1
	if [ "$?" = "0" ];then
		vpnside=`uci get wsdwan.config.selectroute`
	fi
	if [ "$quagga" = "1" ];then
		if [ "$vpnside" = "2" ];then
			routenum=`ip route|grep WSDWAN|wc -l`
			if [ "$routenum" -lt "$routenums" ];then
				sed 's/^/ip route &/g' /etc/chnroute > /etc/quagga/zebra.conf
				sed -i 's/$/& vpn-WSDWAN/g' /etc/quagga/zebra.conf
				/etc/init.d/quagga restart
				/etc/init.d/dnsmasq restart
			fi
		else
			routenum=`ip route|grep WSDWAN|wc -l`
			if [ "$routenum" -lt "2" ];then
				sed 's/^/ip route &/g' /etc/chnroute > /etc/quagga/zebra.conf
				sed -i "s/$/& $NET_GATEWAY/g" /etc/quagga/zebra.conf
				echo "" >>/etc/quagga/zebra.conf
				echo ip route 0.0.0.0/1 vpn-WSDWAN >> /etc/quagga/zebra.conf
				echo ip route 128.0.0.0/1 vpn-WSDWAN >> /etc/quagga/zebra.conf
				/etc/init.d/quagga restart> /dev/null 2>&1
				/etc/init.d/dnsmasq restart> /dev/null 2>&1
			fi
		fi
	else
		if [ "$vpnside" = "2" ];then
			routenum=`ip route|grep WSDWAN|wc -l`
			if [ "$routenum" -lt "$routenums" ];then
				for ip in `cat /etc/chnroute`;do
					ip route add $ip dev vpn-WSDWAN
				done
				/etc/init.d/dnsmasq restart> /dev/null 2>&1
			fi
		else
			routenum=`ip route|grep WSDWAN|wc -l`
			if [ "$routenum" -lt "2" ];then
				for ip in `cat /etc/chnroute`;do
					echo ip route add $ip via $NET_GATEWAY
				done
				ip route 0.0.0.0/1 dev vpn-WSDWAN
				ip route 128.0.0.0/1 dev vpn-WSDWAN
				/etc/init.d/dnsmasq restart> /dev/null 2>&1
			fi
		fi
	fi
	_checkdnsmasq
}


_checkfirewall(){
	if ifconfig vpn-WSDWAN >/dev/null 2>&1;then
	
		iptables -L FORWARD|grep "FORWARD for WSDWAN" >/dev/null 2>&1
		if [ "$?" != "0" ];then
			iptables -I FORWARD -o vpn-WSDWAN -j ACCEPT -m comment --comment "FORWARD for WSDWAN"
		fi
		
		iptables -L INPUT|grep "INPUT1 for WSDWAN" >/dev/null 2>&1
		if [ "$?" != "0" ];then
			iptables -I INPUT -i vpn-WSDWAN -s 10.0.0.0/8 -j DROP -m comment --comment "INPUT1 for WSDWAN"
		fi
		
		iptables -L INPUT|grep "INPUT2 for WSDWAN" >/dev/null 2>&1
		if [ "$?" != "0" ];then
			VPNNETMASK=`uci get wsdwan.config.subnet`
			iptables -I INPUT -i vpn-WSDWAN -s $VPNNETMASK -j ACCEPT -m comment --comment "INPUT2 for WSDWAN"
		fi
		
		iptables -t nat --list|grep "nat for WSDWAN" >/dev/null 2>&1
		if [ "$?" != "0" ];then
			iptables -t nat -A POSTROUTING -o vpn-WSDWAN -j MASQUERADE -m comment --comment "nat for WSDWAN"
		fi
		
	else
	
		iptables -L FORWARD|grep "FORWARD for WSDWAN" >/dev/null 2>&1
		if [ "$?" = "0" ];then
			iptables -D FORWARD -o vpn-WSDWAN -j ACCEPT -m comment --comment "FORWARD for WSDWAN"
		fi
		
		iptables -L INPUT|grep "INPUT1 for WSDWAN" >/dev/null 2>&1
		if [ "$?" = "0" ];then
			iptables -D INPUT -i vpn-WSDWAN -s 10.0.0.0/8 -j DROP -m comment --comment "INPUT1 for WSDWAN"
		fi
		
		iptables -L INPUT|grep "INPUT2 for WSDWAN" >/dev/null 2>&1
		if [ "$?" = "0" ];then
			VPNNETMASK=`uci get wsdwan.config.subnet`
			iptables -D INPUT -i vpn-WSDWAN -s $VPNNETMASK -j ACCEPT -m comment --comment "INPUT2 for WSDWAN"
		fi
		
		iptables -t nat --list|grep "nat for WSDWAN" >/dev/null 2>&1
		if [ "$?" = "0" ];then
			iptables -t nat -D POSTROUTING -o vpn-WSDWAN -j MASQUERADE -m comment --comment "nat for WSDWAN"
		fi
	fi

}


_pre_init() {
	network_find_wan NET_IF
	network_get_ipaddr NET_IP "${NET_IF}"
	network_get_dnsserver NET_DNS "${NET_IF}"
	network_get_gateway NET_GATEWAY "${NET_IF}"
	network_get_device lan lan
	lansub=`ip route|grep $lan|awk '{print $1}'`
	uci get wsdwan.config.subnets|grep $lansub > /dev/null 2>&1
	if [ "$?" != "0" ];then
		uci add_list wsdwan.config.subnets=$lansub
		uci commit wsdwan
	fi
}


_connectvpn(){
	_checklicense
	filepath=$(cd "$(dirname "$0")"; pwd)
	uci set network.WSDWAN=interface
	uci set network.WSDWAN.proto='openconnect'
	uci set network.WSDWAN.auto='0'
	uci set network.WSDWAN.delegate='0'
	uci set network.WSDWAN.defaultroute='0'
	uci set network.WSDWAN.username=$username
	uci set network.WSDWAN.password=$password
	uci set network.WSDWAN.server=$nodename
	uci set network.WSDWAN.port=$port
	uci set network.WSDWAN.authgroup=$authgroup
	uci commit network.WSDWAN

	if uci get firewall.@zone[1].network|grep WSDWAN >/dev/null 2>&1;then
		/etc/init.d/firewall reload
	else
		zone=`uci get firewall.@zone[1].network`
		uci del firewall.@zone[1].network
		uci set firewall.@zone[1].network="$zone WSDWAN"
		uci commit firewall
		/etc/init.d/firewall reload
	fi
	ifup WSDWAN
	sleep 5
	
	#echo $password|openconnect --interface=WSDWAN -b $nodename:$port --user=$username  -s $0
}

_checkvpnconnect(){
	if ifconfig vpn-WSDWAN >/dev/null 2>&1;then
		_checkfirewall
		_checkroute
		_checkneighbor
	else
		_connectvpn
	fi
}

_checkwsdwan(){
	_pre_init
	uci set wsdwan.config.net_if=${NET_IF}
	uci set wsdwan.config.net_ip=${NET_IP}
	uci set wsdwan.config.net_dns=${NET_DNS%%}
	uci set wsdwan.config.net_gateway=${NET_GATEWAY}
	uci commit wsdwan
	if uci get wsdwan.config.enable >/dev/null 2>&1;then
		_checkvpnconnect
	fi
}

_checkupdate(){
	onlinemd5=`curl -s -k -L --connect-timeout 3 https://github.com/hk59775634/luci-app-wsdwan/raw/master/openwrt/md5|tail -1|awk '{print $1}'`
	if [ "${#onlinemd5}" = "32" ];then
		localmd5=`uci get wsdwan.config.version`
		if [ "$onlinemd5" = "$localmd5" ];then
			return 0
		else
			uci set wsdwan.config.update=$onlinemd5
			uci commit wsdwan
			return 1
		fi
	fi
}

_upgrade(){
	onlinemd5=`curl -s -k -L --connect-timeout 3 https://github.com/hk59775634/luci-app-wsdwan/raw/master/openwrt/md5|tail -1|awk '{print $1}'`
	onlineipk=`curl -s -k -L --connect-timeout 3 https://github.com/hk59775634/luci-app-wsdwan/raw/master/openwrt/md5|tail -1|awk '{print $2}'`
	curl -s -L -k --connect-timeout 5 https://github.com/hk59775634/luci-app-wsdwan/raw/master/openwrt/$onlineipk > /tmp/$onlineipk
	tmpmd5=`md5sum /tmp/$onlineipk|awk '{print $1}'`
	if [ "$onlinemd5" = "$tmpmd5" ];then
		opkg install /tmp/$onlineipk --force-depends
		if [ "$?" = "0" ];then
			uci set wsdwan.config.version=$onlinemd5
			uci commit wsdwan
			return 0
		else
			return 1
		fi
	else
		return 1
	fi
}

_checkexp(){
	uci get wsdwan.config.expirationtime > /dev/null 2>&1
	if [ "$?" = "0" ];then
		return 0
	else
		return 1
	fi
}

_checkneighbor(){
	_remove_neighbor
	_apply_neighbor
	

}

_apply_neighbor(){
	uci get wsdwan.config.apitoken >/dev/null 2>&1
	if [ "$?" = "0" ];then
		apitoken=`uci get wsdwan.config.apitoken`
		echo APItoken is $apitoken
	else
		continue
	fi
	
	uci get wsdwan.config.role >/dev/null 2>&1
	if [ "$?" = "0" ];then
		role=`uci get wsdwan.config.role`
	else
		uci set wsdwan.config.role=master
		uci commit wsdwan
		role=master
	fi
	
	for neighborid in `uci show wsdwan|grep neighbor|grep license|awk -F "." '{print $2}'`;do
		uci get wsdwan.$neighborid.license > /dev/null 2>&1
		if [ "$?" = "0" ];then
			neighbor_license=`uci get wsdwan.$neighborid.license`
			echo $neighbor_license
		else
			continue
		fi

		neighbor_address=$(curl -L -s -X GET -H "Authorization: Bearer $apitoken" -H 'X-Requested-With: XMLHttpRequest' -H 'Content-Type: application/json' "https://www.wsdwan.com/api/v1/licenses/$neighbor_license/neighbor")
		echo $neighbor_address|grep Error > /dev/null 2>&1
		if [ "$?" = "0" ];then
			continue
		fi
		uci set wsdwan.$neighborid.address=$neighbor_address
		uci commit wsdwan
		ip route add $neighbor_address dev vpn-WSDWAN > /dev/null 2>&1
		
		iptables -L INPUT|grep "$neighbor_license for WSDWAN"|grep $neighbor_address >/dev/null 2>&1
		if [ "$?" != "0" ];then
			iptables -I INPUT -i vpn-WSDWAN -s $neighbor_address -j ACCEPT -m comment --comment "$neighbor_license for WSDWAN"
		fi
		
		uci get wsdwan.$neighborid.subnets > /dev/null 2>&1
		if [ "$?" = "0" ];then
			neighbor_subnets=`uci get wsdwan.$neighborid.subnets`
			local_license=`uci get wsdwan.config.license`
			local_address=$(curl -L -s -X GET -H "Authorization: Bearer $apitoken" -H 'X-Requested-With: XMLHttpRequest' -H 'Content-Type: application/json' "https://www.wsdwan.com/api/v1/licenses/$local_license/neighbor")
			local_inside_address=`echo $local_address|awk -F "." '{print "100.64.0."$3+1}'`

			if [ "$role" = "master" ];then
				echo -l=7777 > /etc/config/n2n-supernode.conf
				/etc/init.d/supernode enable > /dev/null 2>&1
				/etc/init.d/supernode start > /dev/null 2>&1

				master_license=`echo $local_license`
				master_address=`echo $local_address`
				neighbor_inside_address=`echo $neighbor_address|awk -F "." '{print "100.64.0."$3+1}'`

			else
				master_license=`echo $neighbor_license`
				master_address=`echo $neighbor_address`
				neighbor_inside_address=`echo $master_address|awk -F "." '{print "100.64.0."$3+1}'`
			fi
			#/etc/init.d/edge stop >/dev/null 2>&1
			if ps|grep edge|grep $master_address|grep -v grep;then
				echo "edge is run!"
			else
				killall edge
				/usr/bin/edge -d inside0 -c $master_license -k $apitoken -a $local_inside_address -l $master_address:7777 -r
			fi
#			cat>/tmp/n2n-edge.conf<<EOF
#-d=inside0
#-c=$master_license
#-k=$apitoken
#-a=$local_inside_address
#-p=50001
#-l=$master_address:7777
#-r

#EOF
#			tmpedge=`md5sum /tmp/n2n-edge.conf |awk '{print $1}'`
#			edge=`md5sum /etc/config/n2n-edge.conf |awk '{print $1}'`
#			if [ "$tmpedge" != "$edge" ];then
#				cp -f /tmp/n2n-edge.conf /etc/config/n2n-edge.conf
#				/etc/init.d/edge enable > /dev/null 2>&1
#				/etc/init.d/edge restart > /dev/null 2>&1
#				ip route del $neighbor_subnets >/dev/null 2>&1
#			fi
			
			if ifconfig inside0 >/dev/null 2>&1;then
			
				iptables -L FORWARD|grep "FORWARD for inside0" >/dev/null 2>&1
				if [ "$?" != "0" ];then
					iptables -I FORWARD -i inside0 -j ACCEPT -m comment --comment "FORWARD for inside0"
					iptables -I FORWARD -o inside0 -j ACCEPT -m comment --comment "FORWARD for inside0"
				fi
				
				
				iptables -L INPUT|grep "INPUT for inside0" >/dev/null 2>&1
				if [ "$?" != "0" ];then
					iptables -I INPUT -i inside0 -j ACCEPT -m comment --comment "INPUT for inside0"
				fi
				
#				iptables -t nat --list|grep "nat for inside0" >/dev/null 2>&1
#				if [ "$?" != "0" ];then
#					iptables -t nat -A POSTROUTING -o inside0 -j MASQUERADE -m comment --comment "nat for inside0"
#				fi
			fi
			ip route add $neighbor_subnets via $neighbor_inside_address >/dev/null 2>&1
		fi
	done
}

_remove_neighbor(){
	for removeid in `uci show wsdwan|grep neighbor|grep remove|awk -F"." '{print $2}'`;do
		uci delete wsdwan.$removeid
	done
	uci commit wsdwan
}

_start(){
	_checkpid
	_get_uuid
	_getinfo
	while true;do
		_checkwsdwan
	sleep 5
	done
}

_stop(){
	/etc/init.d/wsdwan stop
}

_reboot(){
	reboot
}

case "$1" in
	stop) 
		_stop
		;;
	checkupdate) 
		_checkupdate
		;;
	upgrade) 
		_upgrade
		;;
	checkexp) 
		_checkexp
		;;
	start)
		_start
		;;
	reboot)
		_reboot
		;;
	checkneighbor)
		_checkneighbor
		;;
esac


