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

INSTALL_DIR="${MCPGATE_INSTALL_DIR:-$HOME/.mcpgate}"
ASSET_BASE="${MCPGATE_ASSET_BASE:-https://mcpgate.de/install}"
COMPOSE_URL="${ASSET_BASE}/docker-compose.yaml"

info() {
  printf '\033[1;34m==>\033[0m %s\n' "$1"
}

warn() {
  printf '\033[1;33m==>\033[0m %s\n' "$1"
}

fail() {
  printf '\033[1;31mError:\033[0m %s\n' "$1" >&2
  exit 1
}

require_cmd() {
  command -v "$1" >/dev/null 2>&1 || fail "Required command not found: $1"
}

download() {
  local url="$1"
  local dest="$2"

  if command -v curl >/dev/null 2>&1; then
    curl -fsSL "$url" -o "$dest"
  elif command -v wget >/dev/null 2>&1; then
    wget -qO "$dest" "$url"
  else
    fail "curl or wget is required to download installation assets"
  fi
}

check_docker_compose() {
  docker compose version >/dev/null 2>&1 || fail "Docker Compose v2 is required (docker compose)"
}

write_env_file() {
  local env_file="$1"
  local base_url="$2"

  if [[ "$base_url" == "http://localhost:8642" ]]; then
    return
  fi

  cat >"$env_file" <<EOF
BASE_URL=${base_url}
CORS_ALLOWED_ORIGINS=${base_url}
EOF
}

wait_for_health() {
  local url="$1"
  local attempts=30

  if ! command -v curl >/dev/null 2>&1; then
    warn "curl is not installed. Skipping local health check."
    return
  fi

  for ((i = 1; i <= attempts; i++)); do
    if curl -fsS "$url" >/dev/null 2>&1; then
      return
    fi
    sleep 2
  done

  warn "mcpgate started, but the health endpoint did not respond yet."
}

main() {
  require_cmd docker
  check_docker_compose

  if [[ -f "${INSTALL_DIR}/docker-compose.yaml" && "${MCPGATE_FORCE:-0}" != "1" ]]; then
    fail "mcpgate is already installed at ${INSTALL_DIR}. To reinstall, run: MCPGATE_FORCE=1 curl -fsSL https://mcpgate.de/install.sh | bash"
  fi

  mkdir -p "$INSTALL_DIR" || fail "Failed to create directory: ${INSTALL_DIR}"

  info "Downloading mcpgate Docker Compose setup"
  download "$COMPOSE_URL" "${INSTALL_DIR}/docker-compose.yaml" || fail "Failed to download docker-compose.yaml from ${COMPOSE_URL}"

  if [[ -n "${MCPGATE_BASE_URL:-}" ]]; then
    info "Writing .env for custom BASE_URL: ${MCPGATE_BASE_URL}"
    write_env_file "${INSTALL_DIR}/.env" "${MCPGATE_BASE_URL}"
  fi

  info "Starting mcpgate"
  if ! docker compose -f "${INSTALL_DIR}/docker-compose.yaml" --project-directory "$INSTALL_DIR" up -d --quiet-pull 2>&1 | grep -i "error\|fail" >&2; then
    true  # suppress normal output, only show errors
  fi

  # Check if containers actually started
  if ! docker compose -f "${INSTALL_DIR}/docker-compose.yaml" --project-directory "$INSTALL_DIR" ps --status running -q 2>/dev/null | grep -q .; then
    fail "Containers failed to start. Run 'cd ${INSTALL_DIR} && docker compose logs' for details."
  fi

  info "Waiting for mcpgate to become healthy"
  wait_for_health "http://localhost:8642/health"

  cat <<EOF

  mcpgate is running on your infrastructure.

  Next steps:
    1. Open http://localhost:8642
    2. Complete the setup wizard
    3. Connect Claude, ChatGPT, Codex, or Gemini from the dashboard

  Manage:
    cd ${INSTALL_DIR}
    docker compose up -d           # start
    docker compose pull && docker compose up -d  # update
    docker compose down            # stop
    docker compose logs            # troubleshoot

EOF
}

main "$@"
