#!/usr/bin/env bash
set -euo pipefail
readonly SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
# shellcheck source=network-common
source "$SCRIPT_DIR/network-common"
network_lock

# Check all chains before detaching any hook. A conflict is a no-change refusal.
for pair in "mangle:$CFPP_PRE_CHAIN" "mangle:$CFPP_OUT_CHAIN" "nat:$CFPP_NAT_CHAIN" "filter:$CFPP_INPUT_CHAIN"; do
  preflight_owned_chain "${pair%%:*}" "${pair#*:}"
done

delete_all_rules() {
	local table=$1
	local chain=$2
	shift 2
	while iptables -t "$table" -C "$chain" "$@" 2>/dev/null; do
		iptables -t "$table" -D "$chain" "$@"
	done
}

delete_all_rules mangle PREROUTING -m comment --comment "$CFPP_COMMENT_PREFIX:hook-pre" -j "$CFPP_PRE_CHAIN"
delete_all_rules mangle OUTPUT -m comment --comment "$CFPP_COMMENT_PREFIX:hook-out" -j "$CFPP_OUT_CHAIN"
delete_all_rules nat PREROUTING -m comment --comment "$CFPP_COMMENT_PREFIX:hook-nat" -j "$CFPP_NAT_CHAIN"
delete_all_rules filter INPUT -m comment --comment "$CFPP_COMMENT_PREFIX:hook-input" -j "$CFPP_INPUT_CHAIN"

remove_owned_chain() {
  local table=$1
  local chain=$2
  if ! iptables -t "$table" -S "$chain" >/dev/null 2>&1; then
    return
  fi
  local foreign
  foreign=$(iptables -t "$table" -S "$chain" | foreign_chain_rules)
  [[ -z "$foreign" ]] || fail "refusing to remove chain $chain because it contains non-gateway rules"
  iptables -t "$table" -F "$chain"
  iptables -t "$table" -X "$chain"
}

remove_owned_chain mangle "$CFPP_PRE_CHAIN"
remove_owned_chain mangle "$CFPP_OUT_CHAIN"
remove_owned_chain nat "$CFPP_NAT_CHAIN"
remove_owned_chain filter "$CFPP_INPUT_CHAIN"
ipset destroy "$CFPP_TRUSTED_V4_SET" 2>/dev/null || true
ipset destroy "$CFPP_DESTINATION_V4_SET" 2>/dev/null || true

remove_docker_routes
rm -f -- "$CFPP_DOCKER_ROUTES_FILE"

if rule_is_installed; then
  ip -4 rule del priority "$CFPP_RULE_PRIORITY" fwmark "$CFPP_MARK_MASK" lookup "$CFPP_ROUTE_TABLE"
fi
if route_is_installed; then
  ip -4 route del local 0.0.0.0/0 dev lo table "$CFPP_ROUTE_TABLE"
fi

if [[ $(<"$CFPP_ROUTE_LOCALNET_PATH") == 1 ]]; then
  printf '%s\n' "$CFPP_ROUTE_LOCALNET_PREVIOUS" >"$CFPP_ROUTE_LOCALNET_PATH"
fi

echo "cf-pp-gateway transparent network rules removed"
