#!/bin/bash
# Start the E2E test network interactively.
#
# Usage:
#   ./bin/e2e-up                          # Infrastructure only
#   ./bin/e2e-up --caddy                  # + caddy machine in dmz
#   ./bin/e2e-up --full-stack             # + caddy, idp, db
#   ./bin/e2e-up --custom '{"dmz":{"caddy":"10.0.10.10","web":"10.0.10.20"}}'
#
# After startup, drops you into a shell on the management machine.
# Use `exit` to leave the shell (network stays running).
# Use `./bin/e2e-down` to tear everything down.

set -e
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
cd "$SCRIPT_DIR"

PROJECT_NAME="conductor-e2e-interactive"

# Parse args
PRESET="infrastructure"
CUSTOM_JSON=""
while [[ $# -gt 0 ]]; do
  case "$1" in
    --caddy) PRESET="caddy"; shift ;;
    --full-stack) PRESET="full-stack"; shift ;;
    --custom) shift; CUSTOM_JSON="$1"; shift ;;
    --help|-h)
      echo "Usage: e2e-up [--caddy|--full-stack|--custom '<json>']"
      echo ""
      echo "Presets:"
      echo "  (default)      Infrastructure only (management, firewalls, DNS, Pebble)"
      echo "  --caddy        + caddy machine at 10.0.10.10 in dmz"
      echo "  --full-stack   + caddy (dmz), idp (app), db (secure)"
      echo "  --custom JSON  Custom machine spec, e.g. '{\"dmz\":{\"caddy\":\"10.0.10.10\"}}'"
      echo ""
      echo "After startup, you'll be dropped into the management machine shell."
      echo "Use ./bin/e2e-down to tear down, or ./bin/e2e-shell to reconnect."
      exit 0
      ;;
    *) shift ;;
  esac
done

# Generate docker-compose.yml
export PRESET CUSTOM_JSON
echo "Generating docker-compose.yml (preset: $PRESET)..."
bun -e "
import { generateComposeYaml } from './src/docker-compose-generator';

const presets = {
  'infrastructure': {
    topology: 'default',
    dmzMachines: [],
    appMachines: [],
    secureMachines: [],
    domain: 'iamtheinternet.org',
    ddnsPassword: 'test123',
    verifyRouting: false,
  },
  'caddy': {
    topology: 'default',
    dmzMachines: [{ name: 'caddy', ip: '10.0.10.10', zone: 'dmz' }],
    appMachines: [],
    secureMachines: [],
    domain: 'iamtheinternet.org',
    ddnsPassword: 'test123',
    verifyRouting: false,
  },
  'full-stack': {
    topology: 'default',
    dmzMachines: [{ name: 'caddy', ip: '10.0.10.10', zone: 'dmz' }],
    appMachines: [{ name: 'idp', ip: '10.0.20.100', zone: 'app' }],
    secureMachines: [{ name: 'db', ip: '10.0.30.50', zone: 'secure' }],
    domain: 'iamtheinternet.org',
    ddnsPassword: 'test123',
    verifyRouting: false,
  },
};

const customJson = process.env.CUSTOM_JSON;
let config;
if (customJson) {
  const spec = JSON.parse(customJson);
  config = { ...presets['infrastructure'] };
  for (const [zone, machines] of Object.entries(spec)) {
    const key = zone + 'Machines';
    if (key in config) {
      config[key] = Object.entries(machines).map(([name, ip]) => ({ name, ip, zone }));
    }
  }
} else {
  config = presets[process.env.PRESET || 'infrastructure'];
}

console.log(generateComposeYaml(config));
" > docker-compose.yml

# Build and start
echo "Building images (this may take a while on first run)..."
docker compose -p "$PROJECT_NAME" build

echo "Starting containers..."
docker compose -p "$PROJECT_NAME" up -d

echo ""
echo "Waiting for management machine to initialize..."
for i in $(seq 1 15); do
  if docker compose -p "$PROJECT_NAME" exec -T management test -f /root/.zshrc 2>/dev/null; then
    break
  fi
  sleep 1
done

echo "Waiting for DNS convergence..."
for i in $(seq 1 30); do
  if docker compose -p "$PROJECT_NAME" exec -T comcast-resolver dig @127.0.0.1 iamtheinternet.org NS +short +timeout=2 2>/dev/null | grep -q '.'; then
    echo "DNS is ready!"
    break
  fi
  if [ "$i" = "30" ]; then
    echo "WARNING: DNS did not converge after 60s. Continuing anyway."
  fi
  sleep 2
done

echo ""
echo "================================================"
echo "  E2E Network is running!"
echo "  Project: $PROJECT_NAME"
echo "================================================"
echo ""
echo "Networks:"
echo "  internal:          192.168.0.0/24"
echo "  dmz:               10.0.10.0/24"
echo "  app:               10.0.20.0/24"
echo "  secure:            10.0.30.0/24"
echo "  isp-external:      100.100.0.0/24"
echo "  internet-external: 100.64.0.0/24"
echo ""
echo "Key machines:"
echo "  management:        192.168.0.100  (conductor CLI)"
echo "  fw-main:           192.168.0.254  (iptables firewall)"
echo "  fw-isp:            192.168.0.1    (greenwave router sim)"
echo "  comcast-resolver:  100.100.0.1        (DNS resolver)"
echo "  namecheap-dns:     100.64.0.55       (DDNS simulator)"
echo "  letsencrypt:       100.64.0.100      (Pebble ACME)"
echo "  apt-cache:         100.64.0.2        (apt proxy → real internet)"
echo ""
echo "Commands:"
echo "  ./bin/e2e-shell                   Reconnect to management"
echo "  ./bin/e2e-shell <container>       Shell into any container"
echo "  ./bin/e2e-down                    Tear everything down"
echo "  docker compose -p $PROJECT_NAME ps    List containers"
echo ""
echo "Dropping you into the management machine..."
echo "(use 'conductor <cmd>' or 'c <cmd>' — tab completion works)"
echo ""

docker compose -p "$PROJECT_NAME" exec management zsh -li
