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

script_path=$(realpath "${BASH_SOURCE[0]}")
script_dir=$(dirname "$script_path")
original_args=("$@")

usage() {
  cat <<'EOF'
usage: pushy-systemd [deploy options]
       pushy-systemd <status|metrics|logs|restart|start|stop> [component]

With no subcommand (or options only), deploy the globally installed package.

commands:
  status                 Show release, services, memory, timer and health
  metrics [api|api-candidate|worker] [process|heap|internal]
                         Read local Unix-socket diagnostics (defaults: api process)
  logs [all|api|worker|dailyjob|marketing]
                         Follow journald logs (default: all)
  restart [all|api|worker]
                         Restart services and show status (default: all)
  start                  Start the target and scheduled timers
  stop                   Stop the target
  swap [size-mib]        Provision a swap file so the cgroups can reclaim
                         anonymous memory (default: RAM/8, clamped 2-4 GiB)

deploy options:
  --bun-bin PATH         Bun executable (default: current PATH)
  --env-file PATH        Environment file (default: inherit, then scan .env.prod/.env.ext/.env)
  --worker               Enable the worker on this host
  --no-worker            Disable the worker on this host (persistent)
EOF
}

worker_is_enabled() {
  [[ ! -e /etc/pushy/worker-disabled ]]
}

as_root() {
  if [[ $EUID -eq 0 ]]; then
    return
  fi
  bun_bin=${PUSHY_BUN_BIN:-$(command -v bun || true)}
  if [[ -n ${PUSHY_ENV_FILE:-} ]]; then
    exec sudo env PUSHY_BUN_BIN="$bun_bin" PUSHY_ENV_FILE="$PUSHY_ENV_FILE" \
      "$script_path" "${original_args[@]}"
  fi
  exec sudo env PUSHY_BUN_BIN="$bun_bin" "$script_path" "${original_args[@]}"
}

configure_host_memory() {
  "$script_dir/configure-host-memory.sh" pushy
  systemctl daemon-reload
}

roll_api() {
  /opt/pushy/current/deploy/systemd/roll-api.sh
}

command_name=${1:-deploy}
case "$command_name" in
  -h|--help|help)
    usage
    exit 0
    ;;
  -*) command_name=deploy ;;
  deploy|install)
    if [[ $# -gt 0 ]]; then shift; fi
    ;;
  status|metrics|logs|restart|start|stop|swap) shift ;;
  *)
    echo "unknown command: $command_name" >&2
    usage >&2
    exit 2
    ;;
esac

case "$command_name" in
  deploy)
    as_root
    exec "$script_dir/bootstrap-host.sh" "$@"
    ;;
  status)
    exec /opt/pushy/current/deploy/systemd/status.sh
    ;;
  metrics)
    component=api
    view=${1:-process}
    if [[ $view == api || $view == api-candidate || $view == api-peer || $view == worker ]]; then
      component=$view
      view=${2:-process}
    fi
    as_root
    case "$view" in
      process) endpoint=/metrics/process ;;
      heap) endpoint='/metrics/heap?objects=1' ;;
      internal) endpoint=/metrics/internal ;;
      *) echo "unknown metrics view: $view" >&2; exit 2 ;;
    esac
    case "$component" in
      api) socket_path=/run/pushy/metrics.sock ;;
      api-candidate) socket_path=/run/pushy-api-candidate/metrics.sock ;;
      api-peer) socket_path=/run/pushy-api-peer/metrics.sock ;; # legacy migration alias
      worker) socket_path=/run/pushy-worker/metrics.sock ;;
      *) echo "unknown metrics component: $component" >&2; exit 2 ;;
    esac
    exec curl --fail --silent --show-error --unix-socket "$socket_path" \
      "http://localhost$endpoint"
    ;;
  logs)
    component=${1:-all}
    as_root
    case "$component" in
      all) exec journalctl -f -u pushy-api.service -u pushy-api-candidate.service -u pushy-worker.service -u pushy-dailyjob.service -u pushy-cresc-ai-marketing.service ;;
      api) exec journalctl -f -u pushy-api.service -u pushy-api-candidate.service ;;
      worker) exec journalctl -f -u pushy-worker.service ;;
      dailyjob) exec journalctl -f -u pushy-dailyjob.service ;;
      marketing) exec journalctl -f -u pushy-cresc-ai-marketing.service ;;
      *) echo "unknown component: $component" >&2; exit 2 ;;
    esac
    ;;
  restart)
    component=${1:-all}
    as_root
    configure_host_memory
    case "$component" in
      all)
        roll_api
        if worker_is_enabled; then
          systemctl restart pushy-worker.service
        else
          systemctl stop pushy-worker.service
        fi
        ;;
      api) roll_api ;;
      worker)
        if ! worker_is_enabled; then
          echo "Pushy worker is disabled on this host; deploy with --worker to enable it" >&2
          exit 1
        fi
        systemctl restart pushy-worker.service
        ;;
      *) echo "unknown component: $component" >&2; exit 2 ;;
    esac
    exec /opt/pushy/current/deploy/systemd/status.sh
    ;;
  start)
    as_root
    configure_host_memory
    systemctl start pushy.target pushy-dailyjob.timer pushy-cresc-ai-marketing.timer pushy-health-watchdog.timer
    exec /opt/pushy/current/deploy/systemd/status.sh
    ;;
  stop)
    as_root
    exec systemctl stop pushy.target
    ;;
  swap)
    as_root
    "$script_dir/ensure-swapfile.sh" "$@"
    # Swap presence changes how wide the MemoryHigh band can safely be, so
    # re-derive the limits instead of waiting for the next deploy.
    configure_host_memory
    exec /opt/pushy/current/deploy/systemd/status.sh
    ;;
esac
