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

FILEDOWN_DIR="${FILEDOWN_DIR:-$HOME/filedown}"
FILEDOWN_IMAGE="${FILEDOWN_IMAGE:-filedown/filedown:latest}"
FILEDOWN_UPDATER_IMAGE="${FILEDOWN_UPDATER_IMAGE:-filedown/updater:latest}"
FILEDOWN_PORT="${FILEDOWN_PORT:-6800}"

info() { echo "[filedown] $*"; }
die() { echo "[filedown] ERROR: $*" >&2; exit 1; }

gen_secret() {
  if command -v openssl >/dev/null 2>&1; then openssl rand -hex 32
  else tr -dc 'a-f0-9' </dev/urandom | head -c 64
  fi
}

port_in_use() {
  local port="$1"
  if command -v ss >/dev/null 2>&1; then
    ss -ltn "( sport = :$port )" 2>/dev/null | tail -n +2 | grep -q .
    return
  fi
  if command -v lsof >/dev/null 2>&1; then
    lsof -iTCP:"$port" -sTCP:LISTEN >/dev/null 2>&1
    return
  fi
  return 1
}

pick_port() {
  local requested="$1"
  local candidate
  if [ -n "${FILEDOWN_PORT:-}" ] && [ "$FILEDOWN_PORT" != "6800" ]; then
    return
  fi
  if ! port_in_use "$requested"; then
    FILEDOWN_PORT="$requested"
    return
  fi
  for candidate in 6801 6802 6803 30180 30181 30182 30800; do
    if ! port_in_use "$candidate"; then
      echo "[filedown] Port $requested is already in use. Using $candidate instead."
      FILEDOWN_PORT="$candidate"
      return
    fi
  done
  die "Could not find a free host port for Filedown. Set FILEDOWN_PORT and rerun this script."
}

command -v docker >/dev/null 2>&1 || die "Docker is required. Install Docker, then rerun this script."
docker compose version >/dev/null 2>&1 || die "Docker Compose v2 is required."
pick_port "$FILEDOWN_PORT"

mkdir -p "$FILEDOWN_DIR"
cd "$FILEDOWN_DIR"

if [ ! -f .env ]; then
  cat > .env <<EOF
FILEDOWN_IMAGE=$FILEDOWN_IMAGE
FILEDOWN_UPDATER_IMAGE=$FILEDOWN_UPDATER_IMAGE
FILEDOWN_PORT=$FILEDOWN_PORT
FILEDOWN_HTTPS=false
FILEDOWN_JWT_SECRET=$(gen_secret)
FILEDOWN_UPDATER_TOKEN=$(gen_secret)
POSTGRES_PASSWORD=$(gen_secret)
POSTGRES_DB=filedown
POSTGRES_USER=filedown
FILEDOWN_INSTALL_TYPE=docker
# Optional: disable anonymous install heartbeat telemetry
# FILEDOWN_TELEMETRY_DISABLED=true
EOF
fi

cat > docker-compose.yml <<'EOF'
services:
  postgres:
    image: postgres:18-alpine
    environment:
      POSTGRES_DB: ${POSTGRES_DB:-filedown}
      POSTGRES_USER: ${POSTGRES_USER:-filedown}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}
    volumes:
      - filedown-postgres:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-filedown} -d ${POSTGRES_DB:-filedown}"]
      interval: 5s
      timeout: 5s
      retries: 20
    restart: unless-stopped

  filedown:
    image: ${FILEDOWN_IMAGE:-filedown/filedown:latest}
    depends_on:
      postgres:
        condition: service_healthy
      updater:
        condition: service_started
    ports:
      - "${FILEDOWN_PORT:-6800}:6800"
    volumes:
      - ./filedown-data:/data
    environment:
      FILEDOWN_JWT_SECRET: ${FILEDOWN_JWT_SECRET:?Set FILEDOWN_JWT_SECRET in .env}
      FILEDOWN_PORT: 6800
      FILEDOWN_DATA_DIR: /data
      FILEDOWN_HTTPS: ${FILEDOWN_HTTPS:-false}
      FILEDOWN_INSTALL_TYPE: ${FILEDOWN_INSTALL_TYPE:-docker}
      FILEDOWN_TELEMETRY_DISABLED: ${FILEDOWN_TELEMETRY_DISABLED:-false}
      FILEDOWN_UPDATER_URL: http://updater:6810
      FILEDOWN_UPDATER_TOKEN: ${FILEDOWN_UPDATER_TOKEN:?Set FILEDOWN_UPDATER_TOKEN in .env}
      PGHOST: postgres
      PGPORT: 5432
      PGUSER: ${POSTGRES_USER:-filedown}
      PGPASSWORD: ${POSTGRES_PASSWORD}
      PGDATABASE: ${POSTGRES_DB:-filedown}
    restart: unless-stopped

  updater:
    image: ${FILEDOWN_UPDATER_IMAGE:-filedown/updater:latest}
    volumes:
      - ./:/filedown
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      FILEDOWN_UPDATER_TOKEN: ${FILEDOWN_UPDATER_TOKEN:?Set FILEDOWN_UPDATER_TOKEN in .env}
      FILEDOWN_DIR: /filedown
      FILEDOWN_SERVICE_NAME: filedown
    restart: unless-stopped

volumes:
  filedown-postgres:
EOF

info "Pulling Filedown images..."
docker compose pull
info "Starting Filedown..."
docker compose up -d
info "Filedown is running at http://localhost:${FILEDOWN_PORT}"
