#!/usr/bin/bash

[ $# -eq 0 ] && echo "$(basename $0) create NAME URL TABLE_ID" && echo "$(basename $0) load|unload|delete NAME" && echo "$(basename $0) list" && echo "$(basename $0) load-private|unload-private TABLE_ID" && exit 0

[ $UID -ne 0 ] && echo "Must be run as root" >&2 && exit 1

! command -v cidr-merger >/dev/null && echo "Missing cidr-merger" >&2 && exit 2
! command -v pv >/dev/null && echo "Missing pv" >&2 && exit 2

CFG_DIR=/etc/exit-node-routes
BACKUP_DIR=/tmp/exit-node-routes

mkdir -p "$CFG_DIR"
mkdir -p "$BACKUP_DIR"

ROUTES=$CFG_DIR/$2
BACKUP=$BACKUP_DIR/$2

PRIVATE_ROUTES="10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 100.64.0.0/10"

case "$1" in
	create)
		[ $# -lt 4 ] && echo "Missing argument(s)" >&2 && exit 3
		[ -f $BACKUP ] && echo "Can't create while loaded" >&2 && exit 3
		[ -f $ROUTES ] && echo "$ROUTES already exists" >&2 && exit 3
		IPS=$(curl $3 2>/dev/null | cidr-merger)
		TOTAL=$(echo "$IPS" | wc -l)
		TABLE=$4
		ip route save table $TABLE > $BACKUP
		ip route flush table $TABLE
		echo "$IPS" | pv -l -s $TOTAL -W | xargs -I '{}' ip route add to throw '{}' table $TABLE
		echo "Created $2 with $TOTAL routes"
		ip route save table $TABLE type throw > $ROUTES
		ip route flush table $TABLE type throw
		ip route restore < $BACKUP
		rm $BACKUP
		;;
	delete)
		[ $# -lt 2 ] && echo "Missing argument(s)" >& 2 && exit 3
		[ ! -f $ROUTES ] && echo "$ROUTES doesn't exist" >&2 && exit 3
		rm $ROUTES
		;;
	list)
		ls $CFG_DIR
		;;
	load)
		[ $# -lt 2 ] && echo "Missing argument(s)" >& 2 && exit 3
		[ ! -f $ROUTES ] && echo "$ROUTES doesn't exist" >&2 && exit 3
		readarray -t TABLES < <(ip route showdump < $ROUTES | grep -E -o "table [0-9]+" | sort | uniq)
		[ ${#TABLES[@]} -ne 1 ] && echo "Unsupported dump" >&2 && exit 4
		TABLE=${TABLES[0]#* }
		[ ! -f $BACKUP ] && ip route save table $TABLE type throw > $BACKUP
		ip route restore < $ROUTES
		;;
	unload)
		[ $# -lt 2 ] && echo "Missing argument(s)" >& 2 && exit 3
		[ ! -f $BACKUP ] && echo "Not loaded" >&2 && exit 3
		readarray -t TABLES < <(ip route showdump < $ROUTES | grep -E -o "table [0-9]+" | sort | uniq)
		[ ${#TABLES[@]} -ne 1 ] && echo "Unsupported dump" >&2 && exit 4
		TABLE=${TABLES[0]#* }
		ip route flush table $TABLE type throw
		ip route restore < $BACKUP
		rm $BACKUP
		;;
	load-private)
		[ $# -lt 2 ] && echo "Missing argument(s)" >& 2 && exit 3
		TABLE=$2
		for PRIVATE_ROUTE in $PRIVATE_ROUTES; do
			ip route add to throw $PRIVATE_ROUTE table $TABLE
		done
		;;
	unload-private)
		[ $# -lt 2 ] && echo "Missing argument(s)" >& 2 && exit 3
		TABLE=$2
		for PRIVATE_ROUTE in $PRIVATE_ROUTES; do
			ip route del to throw $PRIVATE_ROUTE table $TABLE
		done
		;;
	*)
		echo "Unrecognized command" >&2 && exit 3
		;;
esac
