#!/usr/bin/env bash
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
STATE_DIR="$ROOT_DIR/.run"
LOG_DIR="$STATE_DIR/logs"
VENV_DIR="$ROOT_DIR/venv"

mkdir -p "$LOG_DIR"

if [ -f "$ROOT_DIR/.env" ]; then
  set -a
  source "$ROOT_DIR/.env"
  set +a
fi

source "$ROOT_DIR/services/services.sh"

require_venv() {
  if [ ! -f "$VENV_DIR/bin/activate" ]; then
    echo "Missing venv. Run: ./install.sh"
    exit 1
  fi
}

is_running() {
  local name="$1"
  local pid_file="$STATE_DIR/$name.pid"
  if [ ! -f "$pid_file" ]; then
    return 1
  fi
  local pid
  pid="$(cat "$pid_file" 2>/dev/null || true)"
  if [ -z "$pid" ]; then
    return 1
  fi
  kill -0 "$pid" >/dev/null 2>&1
}

start_one() {
  local name="$1"
  local cmd_var="SERVICE_${name}_CMD"
  local cmd
  cmd="${!cmd_var}"
  if [ -z "$cmd" ]; then
    echo "Unknown service: $name"
    exit 1
  fi

  if is_running "$name"; then
    echo "$name already running"
    return 0
  fi

  require_venv
  source "$VENV_DIR/bin/activate"

  local log_file="$LOG_DIR/$name.log"
  local pid_file="$STATE_DIR/$name.pid"

  echo "Starting $name"
  nohup bash -lc "cd \"$ROOT_DIR\" && source \"$VENV_DIR/bin/activate\" && $cmd" >>"$log_file" 2>&1 &
  echo $! >"$pid_file"
}

detect_terminal() {
  if command -v lxterminal >/dev/null 2>&1; then
    echo "lxterminal"
    return 0
  fi
  if command -v gnome-terminal >/dev/null 2>&1; then
    echo "gnome-terminal"
    return 0
  fi
  if command -v xterm >/dev/null 2>&1; then
    echo "xterm"
    return 0
  fi
  return 1
}

start_one_term() {
  local name="$1"
  local cmd_var="SERVICE_${name}_CMD"
  local cmd
  cmd="${!cmd_var}"
  if [ -z "$cmd" ]; then
    echo "Unknown service: $name"
    exit 1
  fi

  if is_running "$name"; then
    echo "$name already running"
    return 0
  fi

  require_venv

  local term
  term="$(detect_terminal || true)"
  if [ -z "$term" ]; then
    echo "No supported terminal found (need lxterminal, gnome-terminal, or xterm)"
    exit 1
  fi

  local log_file="$LOG_DIR/$name.log"
  local pid_file="$STATE_DIR/$name.pid"
  local title="RoboVision:$name"
  local run_cmd
  run_cmd="cd \"$ROOT_DIR\" && source \"$VENV_DIR/bin/activate\" && exec $cmd"

  echo "Starting $name in terminal ($term)"

  if [ "$term" = "lxterminal" ]; then
    lxterminal --title="$title" --command="bash -lc '$run_cmd'" >>"$log_file" 2>&1 &
    echo $! >"$pid_file"
    return 0
  fi

  if [ "$term" = "gnome-terminal" ]; then
    gnome-terminal --title="$title" -- bash -lc "$run_cmd" >>"$log_file" 2>&1 &
    echo $! >"$pid_file"
    return 0
  fi

  if [ "$term" = "xterm" ]; then
    xterm -T "$title" -e bash -lc "$run_cmd" >>"$log_file" 2>&1 &
    echo $! >"$pid_file"
    return 0
  fi
}

stop_one() {
  local name="$1"
  local pid_file="$STATE_DIR/$name.pid"

  if ! is_running "$name"; then
    rm -f "$pid_file"
    echo "$name not running"
    return 0
  fi

  local pid
  pid="$(cat "$pid_file")"
  echo "Stopping $name (pid $pid)"
  kill "$pid" >/dev/null 2>&1 || true

  local i
  for i in $(seq 1 30); do
    if kill -0 "$pid" >/dev/null 2>&1; then
      sleep 0.2
    else
      break
    fi
  done

  if kill -0 "$pid" >/dev/null 2>&1; then
    kill -9 "$pid" >/dev/null 2>&1 || true
  fi

  rm -f "$pid_file"
}

status_one() {
  local name="$1"
  local port_var="SERVICE_${name}_PORT"
  local port
  port="${!port_var}"

  if is_running "$name"; then
    echo "$name: running (port ${port:-n/a})"
  else
    echo "$name: stopped"
  fi
}

tail_one() {
  local name="$1"
  local log_file="$LOG_DIR/$name.log"
  if [ ! -f "$log_file" ]; then
    echo "No log file: $log_file"
    exit 1
  fi
  tail -n 200 -f "$log_file"
}

usage() {
  echo "Usage: ./run.sh <start|start-term|stop|restart|status|logs> [service]"
  echo "Services: ${SERVICES[*]}"
}

ACTION="${1:-}"
NAME="${2:-all}"

case "$ACTION" in
  start)
    if [ "$NAME" = "all" ]; then
      for s in "${SERVICES[@]}"; do start_one "$s"; done
    else
      start_one "$NAME"
    fi
    ;;
  start-term)
    if [ "$NAME" = "all" ]; then
      for s in "${SERVICES[@]}"; do start_one_term "$s"; done
    else
      start_one_term "$NAME"
    fi
    ;;
  stop)
    if [ "$NAME" = "all" ]; then
      for s in "${SERVICES[@]}"; do stop_one "$s"; done
    else
      stop_one "$NAME"
    fi
    ;;
  restart)
    if [ "$NAME" = "all" ]; then
      for s in "${SERVICES[@]}"; do stop_one "$s"; done
      for s in "${SERVICES[@]}"; do start_one "$s"; done
    else
      stop_one "$NAME"
      start_one "$NAME"
    fi
    ;;
  status)
    if [ "$NAME" = "all" ]; then
      for s in "${SERVICES[@]}"; do status_one "$s"; done
    else
      status_one "$NAME"
    fi
    ;;
  logs)
    if [ "$NAME" = "all" ]; then
      echo "Specify a service for logs"
      exit 1
    fi
    tail_one "$NAME"
    ;;
  *)
    usage
    exit 1
    ;;
esac
