#!/usr/bin/env bash
# setup_registry_api — Deploy completo de registry_api en VPS con Docker + Traefik (Coolify proxy)
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REGISTRY_ROOT="$(cd "$SCRIPT_DIR/../../../../" && pwd)"

source "$SCRIPT_DIR/rsync_deploy.sh"

setup_registry_api() {
    local ssh_host="${1:-organic-machine.com}"
    local api_token="${2:-}"
    local basic_auth_user="${3:-lucas}"
    local basic_auth_pass="${4:-}"

    if [[ -z "$api_token" ]]; then
        echo "setup_registry_api: REGISTRY_API_TOKEN es obligatorio (parametro 2)" >&2
        return 1
    fi

    if [[ -z "$basic_auth_pass" ]]; then
        echo "setup_registry_api: basic_auth_pass es obligatorio (parametro 4)" >&2
        return 1
    fi

    local start_ts
    start_ts=$(date +%s)

    # 1. Verificar conectividad SSH
    echo "==> [1/7] Verificando conectividad SSH a '$ssh_host'..." >&2
    if ! ssh -o BatchMode=yes -o ConnectTimeout=10 "$ssh_host" true 2>/dev/null; then
        echo "setup_registry_api: no se puede conectar a '$ssh_host' via SSH" >&2
        return 1
    fi
    echo "    OK: SSH conectado." >&2

    # 2. Generar hash bcrypt para basicAuth de Traefik
    echo "==> [2/7] Generando hash bcrypt para basicAuth..." >&2
    if ! command -v htpasswd &>/dev/null; then
        echo "setup_registry_api: 'htpasswd' no encontrado. Instalar con: apt install apache2-utils" >&2
        return 1
    fi
    local traefik_hash
    traefik_hash=$(htpasswd -nbB "$basic_auth_user" "$basic_auth_pass" 2>/dev/null)
    if [[ -z "$traefik_hash" ]]; then
        echo "setup_registry_api: htpasswd no generó un hash válido" >&2
        return 1
    fi
    # For Traefik file provider, use single $ (NOT $$ — that's only for Docker labels)
    echo "    OK: hash generado para usuario '$basic_auth_user'." >&2

    # 3. Subir el repo completo al VPS via rsync (el Dockerfile necesita el contexto completo)
    local remote_build_dir="/opt/fn-registry-build"
    echo "==> [3/7] Sincronizando repo a '$ssh_host:$remote_build_dir' via rsync..." >&2
    rsync_deploy "$REGISTRY_ROOT/" "$ssh_host" "$remote_build_dir" >/dev/null || {
        echo "setup_registry_api: rsync falló" >&2
        return 1
    }
    echo "    OK: repo sincronizado." >&2

    # 4. Subir traefik-dynamic.yml con el hash real a la ruta de Coolify
    local traefik_dynamic_path="/data/coolify/proxy/dynamic/registry-api-organic-machine-com.yml"
    echo "==> [4/7] Generando y subiendo traefik-dynamic.yml a '$ssh_host:$traefik_dynamic_path'..." >&2

    # Leer el template local y sustituir el placeholder
    local traefik_template
    traefik_template=$(< "$REGISTRY_ROOT/apps/registry_api/traefik-dynamic.yml")
    # Reemplazar la línea del usuario placeholder con el hash real
    local traefik_rendered
    traefik_rendered=$(echo "$traefik_template" | sed "s|.*PLACEHOLDER_BASICAUTH_LINE.*|          - \"${traefik_hash}\"|g")

    # Crear directorio si no existe y subir
    ssh "$ssh_host" "sudo mkdir -p /data/coolify/proxy/dynamic/" >&2
    echo "$traefik_rendered" | ssh "$ssh_host" \
        "sudo tee '$traefik_dynamic_path' > /dev/null"
    echo "    OK: traefik-dynamic.yml desplegado en '$traefik_dynamic_path'." >&2

    # 5. Crear .env en el VPS con el token de la API
    local remote_app_dir="$remote_build_dir/apps/registry_api"
    echo "==> [5/7] Creando .env en '$ssh_host:$remote_app_dir'..." >&2
    ssh "$ssh_host" "cat > '$remote_app_dir/.env'" <<EOF
REGISTRY_API_TOKEN=${api_token}
EOF
    echo "    OK: .env creado." >&2

    # 6. Verificar que la red coolify existe; si no, crearla
    echo "==> [6/7] Verificando red Docker 'coolify' y levantando el stack..." >&2
    ssh "$ssh_host" bash <<'REMOTE'
        set -euo pipefail
        if ! docker network ls --format '{{.Name}}' | grep -q '^coolify$'; then
            echo "  Creando red Docker 'coolify'..."
            docker network create coolify
        fi
        echo "  Red 'coolify' disponible."
REMOTE

    # docker compose build && up desde el directorio de la app (contexto es ../../ = remote_build_dir)
    ssh "$ssh_host" bash <<REMOTE
        set -euo pipefail
        cd '$remote_app_dir'
        echo "  docker compose build..."
        docker compose build
        echo "  docker compose up -d..."
        docker compose up -d
        echo "  Contenedor levantado."
REMOTE
    echo "    OK: stack Docker levantado." >&2

    # 7. Health check
    local health_url="https://registry.organic-machine.com/api/status"
    echo "==> [7/7] Esperando health check en '$health_url'..." >&2
    local attempts=0
    local max_attempts=12
    local status_code=""
    while [[ $attempts -lt $max_attempts ]]; do
        status_code=$(curl -sk -o /dev/null -w "%{http_code}" \
            -u "${basic_auth_user}:${basic_auth_pass}" \
            "$health_url" 2>/dev/null || echo "000")
        if [[ "$status_code" == "200" ]]; then
            break
        fi
        attempts=$((attempts + 1))
        echo "    Intento $attempts/$max_attempts — HTTP $status_code, esperando 10s..." >&2
        sleep 10
    done

    local end_ts
    end_ts=$(date +%s)
    local duration_ms=$(( (end_ts - start_ts) * 1000 ))

    if [[ "$status_code" != "200" ]]; then
        printf '{"status":"error","url":"%s","http_code":"%s","duration_ms":%d,"msg":"health check timeout tras %d intentos"}\n' \
            "$health_url" "$status_code" "$duration_ms" "$max_attempts"
        return 1
    fi

    echo "    OK: servicio respondiendo HTTP 200." >&2
    printf '{"status":"ok","url":"%s","http_code":"%s","duration_ms":%d,"ssh_host":"%s","remote_dir":"%s"}\n' \
        "$health_url" "$status_code" "$duration_ms" "$ssh_host" "$remote_app_dir"
}

if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
    # Uso: setup_registry_api.sh [ssh_host] [api_token] [basic_auth_user] [basic_auth_pass]
    # Variables de entorno alternativas: SSH_HOST, REGISTRY_API_TOKEN, BASIC_AUTH_USER, BASIC_AUTH_PASS
    setup_registry_api \
        "${1:-${SSH_HOST:-organic-machine.com}}" \
        "${2:-${REGISTRY_API_TOKEN:-}}" \
        "${3:-${BASIC_AUTH_USER:-lucas}}" \
        "${4:-${BASIC_AUTH_PASS:-}}"
fi
