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

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
RUN_DIR="$ROOT_DIR/.run"
PID_FILE="$RUN_DIR/visual-chat-8018.pid"
LOG_FILE="$RUN_DIR/visual-chat-8018.log"
ENV_FILE="$ROOT_DIR/.env"

mkdir -p "$RUN_DIR"

if [[ -f "$ENV_FILE" ]]; then
  set -a
  # shellcheck disable=SC1090
  source "$ENV_FILE"
  set +a
fi

HOST="${WEBRTC_HOST:-0.0.0.0}"
PORT="${WEBRTC_PORT:-8018}"
SSL_CERTFILE="${SSL_CERTFILE:-$ROOT_DIR/certs/dev-cert.pem}"
SSL_KEYFILE="${SSL_KEYFILE:-$ROOT_DIR/certs/dev-key.pem}"

if [[ -x "$ROOT_DIR/.venv/bin/python" ]]; then
  PYTHON_BIN="$ROOT_DIR/.venv/bin/python"
else
  PYTHON_BIN="$(command -v python3 || true)"
fi

if [[ -z "$PYTHON_BIN" ]]; then
  echo "python3 not found"
  exit 1
fi

port_pids() {
  ss -ltnp 2>/dev/null \
    | sed -n "s/.*:${PORT} .*users:((\"python\",pid=\([0-9]\+\),.*/\1/p" \
    | tr '\n' ' '
}

is_running() {
  if [[ ! -f "$PID_FILE" ]]; then
    return 1
  fi
  local pid
  pid="$(cat "$PID_FILE")"
  [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null
}

start() {
  if is_running; then
    echo "already running: pid=$(cat "$PID_FILE")"
    return 0
  fi

  local stale
  stale="$(port_pids)"
  if [[ -n "${stale// /}" ]]; then
    echo "killing stale python on port ${PORT}: $stale"
    # shellcheck disable=SC2086
    kill $stale || true
    sleep 1
  fi

  local args
  args=(main:app --host "$HOST" --port "$PORT")
  if [[ -n "$SSL_CERTFILE" && -n "$SSL_KEYFILE" ]]; then
    args+=(--ssl-certfile "$SSL_CERTFILE" --ssl-keyfile "$SSL_KEYFILE")
  fi

  nohup "$PYTHON_BIN" -m uvicorn "${args[@]}" >>"$LOG_FILE" 2>&1 &
  local pid=$!
  echo "$pid" >"$PID_FILE"
  sleep 1

  if kill -0 "$pid" 2>/dev/null; then
    echo "started: pid=$pid"
    echo "url: https://$HOST:$PORT"
    echo "log: $LOG_FILE"
  else
    echo "failed to start, see log: $LOG_FILE"
    rm -f "$PID_FILE"
    return 1
  fi
}

stop() {
  if ! is_running; then
    echo "not running"
    rm -f "$PID_FILE"
    return 0
  fi

  local pid
  pid="$(cat "$PID_FILE")"
  kill "$pid" || true

  for _ in {1..20}; do
    if ! kill -0 "$pid" 2>/dev/null; then
      break
    fi
    sleep 0.2
  done

  if kill -0 "$pid" 2>/dev/null; then
    kill -9 "$pid" || true
  fi

  rm -f "$PID_FILE"
  echo "stopped"
}

status() {
  if is_running; then
    echo "running: pid=$(cat "$PID_FILE")"
    return 0
  fi
  echo "not running"
  return 1
}

logs() {
  if [[ -f "$LOG_FILE" ]]; then
    tail -n 120 "$LOG_FILE"
  else
    echo "no log file yet"
  fi
}

restart() {
  stop || true
  start
}

case "${1:-}" in
  start) start ;;
  stop) stop ;;
  status) status ;;
  restart) restart ;;
  logs) logs ;;
  *)
    echo "usage: $0 {start|stop|status|restart|logs}"
    exit 2
    ;;
esac
