#!/usr/bin/env bash
# ------------------------------------------------------------------------------
# Securely expose Docker API on TCP port 2375 (Tailscale-only access)
# Compatible with ufw — uses iptables DOCKER-USER + systemd unit
# ------------------------------------------------------------------------------
set -euo pipefail

# --- ROOT CHECK ---------------------------------------------------------------
if [[ "$EUID" -ne 0 ]]; then
  echo "❌ Ce script doit être exécuté avec les droits administrateur (root ou sudo)."
  exit 1
fi

# --- MARKERS & FLAGS ----------------------------------------------------------
MARKER_DOCKER="docker_tcp_configured"
MARKER_FIREWALL="docker_tcp_firewall_ok"
FORCE=false
UNINSTALL=false

for arg in "$@"; do
  case "$arg" in
    --force) FORCE=true ;;
    --uninstall) UNINSTALL=true ;;
  esac
done

# --- SHARED FUNCTIONS ---------------------------------------------------------
SHARED_FUNCTIONS="/opt/scripts_local/shared_functions.sh"
if [[ -f "$SHARED_FUNCTIONS" ]]; then
  source "$SHARED_FUNCTIONS"
else
  log(){ echo -e "[docker-tcp-expose] $*"; }
  setup_marker(){ :; }
fi

# --- CONFIGURATION ------------------------------------------------------------
DOCKER_TCP_PORT=2375
TAILSCALE_SUBNETS=(
  "100.100.10.0/24"
  "100.100.111.0/24"
  "100.100.13.0/24"
)
DOCKER_OVERRIDE_DIR="/etc/systemd/system/docker.service.d"
DOCKER_OVERRIDE_FILE="$DOCKER_OVERRIDE_DIR/override.conf"
EXPECTED_EXEC="/usr/bin/dockerd -H tcp://0.0.0.0:${DOCKER_TCP_PORT} -H unix:///var/run/docker.sock"

SYSTEMD_FIREWALL_UNIT="/etc/systemd/system/docker-firewall.service"
FIREWALL_SCRIPT="/usr/local/bin/docker_firewall.sh"

# === UNINSTALL ================================================================
if [[ "$UNINSTALL" == "true" ]]; then
  log "🧹 Mode désinstallation : Docker TCP + firewall"

  if [[ -f "$DOCKER_OVERRIDE_FILE" ]]; then
    sudo rm -f "$DOCKER_OVERRIDE_FILE"
    log "🗑 Docker override supprimé"
    sudo systemctl daemon-reexec
    sudo systemctl daemon-reload
    sudo systemctl restart docker
  fi

  log "🧽 Suppression des règles DOCKER-USER sur le port $DOCKER_TCP_PORT"
  sudo iptables -S DOCKER-USER | grep -- "--dport $DOCKER_TCP_PORT" | while read -r rule; do
    sudo iptables -D DOCKER-USER $rule || true
  done

  log "🧽 Suppression du unit systemd et script firewall Docker"
  sudo systemctl disable --now docker-firewall.service || true
  sudo rm -f "$SYSTEMD_FIREWALL_UNIT" "$FIREWALL_SCRIPT"
  sudo systemctl daemon-reload

  setup_marker delete "$MARKER_DOCKER"
  setup_marker delete "$MARKER_FIREWALL"

  log "✅ Désinstallation terminée."
  exit 0
fi

# === DOCKER CONFIGURATION =====================================================
setup_marker check "$MARKER_DOCKER" "$FORCE"
RECONFIGURE_DOCKER=false
if [[ "$FORCE" == "true" ]] || [[ ! -f "$DOCKER_OVERRIDE_FILE" ]] || ! grep -q "$EXPECTED_EXEC" "$DOCKER_OVERRIDE_FILE"; then
  RECONFIGURE_DOCKER=true
fi

if [[ "$RECONFIGURE_DOCKER" == "true" ]]; then
  log "🔧 (Docker) Configuration requise..."
  sudo mkdir -p "$DOCKER_OVERRIDE_DIR"
  sudo tee "$DOCKER_OVERRIDE_FILE" >/dev/null <<EOF
[Service]
ExecStart=
ExecStart=$EXPECTED_EXEC
EOF
  log "🔄 (Docker) Reload + restart..."
  sudo systemctl daemon-reexec
  sudo systemctl daemon-reload
  sudo systemctl restart docker
  setup_marker create "$MARKER_DOCKER"
else
  log "✅ (Docker) Configuration déjà en place"
fi

# === FIREWALL CONFIGURATION ===================================================
setup_marker check "$MARKER_FIREWALL" "$FORCE"
log "🛡️ (Firewall) Création du script DOCKER-USER..."
sudo tee "$FIREWALL_SCRIPT" >/dev/null <<EOF
#!/bin/bash
iptables -F DOCKER-USER
EOF
for subnet in "${TAILSCALE_SUBNETS[@]}"; do
  echo "iptables -A DOCKER-USER -s $subnet -p tcp --dport $DOCKER_TCP_PORT -j ACCEPT" | sudo tee -a "$FIREWALL_SCRIPT" >/dev/null
done
echo "iptables -A DOCKER-USER -p tcp --dport $DOCKER_TCP_PORT -j DROP" | sudo tee -a "$FIREWALL_SCRIPT" >/dev/null
sudo chmod +x "$FIREWALL_SCRIPT"

log "📦 (Firewall) Création du unit systemd..."
sudo tee "$SYSTEMD_FIREWALL_UNIT" >/dev/null <<EOF
[Unit]
Description=Firewall rules for Docker TCP port 2375
After=network.target docker.service ufw.service
Requires=docker.service

[Service]
Type=oneshot
ExecStart=$FIREWALL_SCRIPT
RemainAfterExit=true

[Install]
WantedBy=multi-user.target
EOF

log "🔁 (Firewall) Activation du service"
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl enable --now docker-firewall.service
setup_marker create "$MARKER_FIREWALL"

# === TESTS ====================================================================
log "🧪 Test d’écoute locale sur port $DOCKER_TCP_PORT..."
if ss -tlpn | grep ":$DOCKER_TCP_PORT" >/dev/null; then
  log "✅ Docker écoute sur :$DOCKER_TCP_PORT"
else
  log "❌ Docker n'écoute PAS sur :$DOCKER_TCP_PORT"
fi

log "🌐 Test API Docker local :"
curl -s --max-time 5 "http://localhost:$DOCKER_TCP_PORT/version" | jq || log "⚠️ Échec ou jq non installé"

log "📍 Terminé : Docker exposé via TCP et sécurisé via DOCKER-USER + systemd"
