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

BRIDGE="br-soria-svc"
NAMESPACES=("soria-svc" "soria-web" "soria-cli")

require_root() {
  if [[ "${EUID}" -ne 0 ]]; then
    echo "Run this script with sudo." >&2
    exit 1
  fi
}

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
}

down() {
  for ns in "${NAMESPACES[@]}"; do
    kill_namespace_processes "${ns}"
    ip netns del "${ns}" 2>/dev/null || true
  done
  ip link del "${BRIDGE}" 2>/dev/null || true
  rm -f /tmp/soria-dhcp.leases \
        /tmp/soria-dnsmasq-dhcp.pid \
        /tmp/soria-dnsmasq-dns.pid \
        /tmp/soria-dhcp-dns \
        /tmp/soria-dnsmasq.conf \
        /tmp/soria-lab.crt \
        /tmp/soria-lab.key
}

attach_namespace() {
  local ns="$1"
  local host_if="$2"
  local ns_if="$3"

  ip link add "${host_if}" type veth peer name "${ns_if}"
  ip link set "${host_if}" master "${BRIDGE}"
  ip link set "${host_if}" up
  ip link set "${ns_if}" netns "${ns}"
  ip -n "${ns}" link set "${ns_if}" name eth0
  ip -n "${ns}" link set lo up
  ip -n "${ns}" link set eth0 up
}

up() {
  down

  ip link add "${BRIDGE}" type bridge
  ip link set "${BRIDGE}" up

  for ns in "${NAMESPACES[@]}"; do
    ip netns add "${ns}"
  done

  attach_namespace "soria-svc" "v-svc" "e-svc"
  attach_namespace "soria-web" "v-web" "e-web"
  attach_namespace "soria-cli" "v-cli" "e-cli"

  ip -n soria-svc addr add 10.30.0.1/24 dev eth0
  ip -n soria-web addr add 10.30.0.20/24 dev eth0

  echo "SORIA services lab is ready."
  status
}

status() {
  echo
  echo "Bridge:"
  ip -brief link show "${BRIDGE}" 2>/dev/null || true

  for ns in "${NAMESPACES[@]}"; do
    echo
    echo "[${ns}]"
    ip -n "${ns}" -brief link 2>/dev/null || true
    ip -n "${ns}" -brief address 2>/dev/null || true
    ip -n "${ns}" route 2>/dev/null || true
  done
}

require_root

case "${1:-}" in
  up)
    up
    ;;
  down)
    down
    ;;
  reset)
    up
    ;;
  status)
    status
    ;;
  *)
    echo "Usage: sudo $0 {up|down|reset|status}" >&2
    exit 2
    ;;
esac
