#!/usr/bin/env bash
set -euo pipefail

MODE="${1:-}"
CLI="m4n-cli"
SRV="m4n-srv"
R1="m4n-r1"
WAN="m4n-wan"

usage() {
  cat <<'EOF'
Usage:
  sudo ./module4-nat-lab.sh setup
  sudo ./module4-nat-lab.sh cleanup
EOF
}

kill_namespace_processes() {
  local ns="$1"
  local pids
  pids="$(ip netns pids "$ns" 2>/dev/null || true)"
  if [[ -n "$pids" ]]; then
    kill $pids 2>/dev/null || true
    sleep 0.2
  fi
}

cleanup() {
  for ns in "$CLI" "$SRV" "$R1" "$WAN"; do
    kill_namespace_processes "$ns"
    ip netns del "$ns" 2>/dev/null || true
  done
  rm -f /tmp/m4-nat.nft
}

create_ns() {
  local ns="$1"
  ip netns add "$ns"
  ip -n "$ns" link set lo up
}

link_namespaces() {
  local ns_a="$1" root_a="$2" if_a="$3"
  local ns_b="$4" root_b="$5" if_b="$6"

  ip link add "$root_a" type veth peer name "$root_b"
  ip link set "$root_a" netns "$ns_a"
  ip link set "$root_b" netns "$ns_b"
  ip -n "$ns_a" link set "$root_a" name "$if_a"
  ip -n "$ns_b" link set "$root_b" name "$if_b"
  ip -n "$ns_a" link set "$if_a" up
  ip -n "$ns_b" link set "$if_b" up
}

setup() {
  cleanup
  for ns in "$CLI" "$SRV" "$R1" "$WAN"; do
    create_ns "$ns"
  done

  link_namespaces "$CLI" ceth eth0 "$R1" rcli lan0
  link_namespaces "$SRV" seth eth0 "$R1" rsrv srv0
  link_namespaces "$WAN" weth eth0 "$R1" rwan wan0

  ip -n "$CLI" addr add 10.50.20.21/24 dev eth0
  ip -n "$SRV" addr add 10.50.30.10/24 dev eth0
  ip -n "$WAN" addr add 203.0.113.2/24 dev eth0

  ip -n "$R1" addr add 10.50.20.1/24 dev lan0
  ip -n "$R1" addr add 10.50.30.1/24 dev srv0
  ip -n "$R1" addr add 203.0.113.1/24 dev wan0

  ip -n "$CLI" route add default via 10.50.20.1
  ip -n "$SRV" route add default via 10.50.30.1
  ip netns exec "$R1" sysctl -qw net.ipv4.ip_forward=1

  cat <<'EOF'
Laboratoire NAT prêt.

Réseaux :
  client  : 10.50.20.21/24
  serveur : 10.50.30.10/24
  routeur : 203.0.113.1/24 côté WAN
  externe : 203.0.113.2/24

Aucune route vers 10.50.0.0/16 n'est ajoutée dans m4n-wan.
EOF
}

if [[ ${EUID} -ne 0 ]]; then
  echo "Exécute ce script avec sudo." >&2
  exit 1
fi

case "$MODE" in
  setup) setup ;;
  cleanup)
    cleanup
    echo "Laboratoire supprimé."
    ;;
  *)
    usage
    exit 1
    ;;
esac
