#!/usr/bin/env bash
# ==============================================
# sync-secrets.sh — Pull secrets from Infisical vault into .env
# ==============================================
#
# Usage:
#   ./scripts/sync-secrets.sh              # Export prod secrets to .env
#   ./scripts/sync-secrets.sh dev          # Export dev secrets to .env.local
#   ./scripts/sync-secrets.sh --verify     # Verify secrets match without overwriting
#
# Prerequisites:
#   - Infisical CLI installed (apt install infisical)
#   - Infisical running on localhost:8084
#   - INFISICAL_TOKEN set (or sourced from /home/dev/shared/secure/credentials/infisical/admin.env)
#
# This script pulls secrets from Infisical and writes them to the project .env file.
# Infisical is the source of truth; .env is a derived artifact for Docker Compose consumption.

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
INFISICAL_DOMAIN="http://127.0.0.1:8084"
INFISICAL_PROJECT_ID="d586d37a-4e9f-4458-8c93-df2fbca060e7"

# Source Infisical token if not set
if [[ -z "${INFISICAL_TOKEN:-}" ]]; then
    CREDS_FILE="/home/dev/shared/secure/credentials/infisical/admin.env"
    if [[ -f "$CREDS_FILE" ]]; then
        INFISICAL_TOKEN=$(grep "^INFISICAL_ADMIN_TOKEN=" "$CREDS_FILE" | cut -d= -f2-)
        export INFISICAL_TOKEN
    else
        echo "ERROR: INFISICAL_TOKEN not set and $CREDS_FILE not found"
        echo "Set INFISICAL_TOKEN or ensure Infisical credentials are available"
        exit 1
    fi
fi

# Determine environment and output file
ENV="${1:-prod}"
VERIFY_MODE=false

if [[ "$ENV" == "--verify" ]]; then
    VERIFY_MODE=true
    ENV="prod"
fi

case "$ENV" in
    prod)
        OUTPUT_FILE="$PROJECT_DIR/.env"
        ;;
    dev)
        OUTPUT_FILE="$PROJECT_DIR/frontend/.env.local"
        ;;
    staging)
        OUTPUT_FILE="$PROJECT_DIR/.env.staging"
        ;;
    *)
        echo "ERROR: Unknown environment '$ENV'. Use: prod, dev, staging"
        exit 1
        ;;
esac

# Check Infisical is reachable
if ! curl -sf "$INFISICAL_DOMAIN/api/status" > /dev/null 2>&1; then
    echo "ERROR: Infisical not reachable at $INFISICAL_DOMAIN"
    echo "Start it: cd /home/dev/shared/infisical && docker compose up -d"
    exit 1
fi

echo "Pulling secrets from Infisical (env=$ENV)..."

# Export secrets
EXPORTED=$(infisical export \
    --domain="$INFISICAL_DOMAIN" \
    --projectId="$INFISICAL_PROJECT_ID" \
    --env="$ENV" \
    --format=dotenv 2>&1)

SECRET_COUNT=$(echo "$EXPORTED" | grep -c "=")

if [[ "$SECRET_COUNT" -eq 0 ]]; then
    echo "ERROR: No secrets returned from Infisical for env=$ENV"
    exit 1
fi

if $VERIFY_MODE; then
    if [[ ! -f "$OUTPUT_FILE" ]]; then
        echo "VERIFY FAILED: $OUTPUT_FILE does not exist"
        exit 1
    fi
    CURRENT_COUNT=$(grep -c "=" "$OUTPUT_FILE" 2>/dev/null || echo 0)
    echo "Infisical: $SECRET_COUNT secrets"
    echo "Local:     $CURRENT_COUNT secrets in $OUTPUT_FILE"

    # Compare keys
    INFISICAL_KEYS=$(echo "$EXPORTED" | grep "=" | sed 's/=.*//' | sort)
    LOCAL_KEYS=$(grep "=" "$OUTPUT_FILE" | grep -v "^#" | sed 's/=.*//' | sort)

    MISSING=$(comm -23 <(echo "$INFISICAL_KEYS") <(echo "$LOCAL_KEYS"))
    EXTRA=$(comm -13 <(echo "$INFISICAL_KEYS") <(echo "$LOCAL_KEYS"))

    if [[ -n "$MISSING" ]]; then
        echo "Missing from local .env:"
        echo "$MISSING" | sed 's/^/  - /'
    fi
    if [[ -n "$EXTRA" ]]; then
        echo "Extra in local .env (not in Infisical):"
        echo "$EXTRA" | sed 's/^/  - /'
    fi
    if [[ -z "$MISSING" && -z "$EXTRA" ]]; then
        echo "VERIFY OK: All keys match"
    fi
    exit 0
fi

# Write secrets
echo "# Auto-generated from Infisical vault — $(date -u +%Y-%m-%dT%H:%M:%SZ)" > "$OUTPUT_FILE"
echo "# Source of truth: Infisical @ $INFISICAL_DOMAIN (project: llmhosts, env: $ENV)" >> "$OUTPUT_FILE"
echo "# Re-sync: ./scripts/sync-secrets.sh $ENV" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
echo "$EXPORTED" >> "$OUTPUT_FILE"

chmod 600 "$OUTPUT_FILE"

# Also update backup
BACKUP_DIR="/home/dev/shared/secure/credentials/llmhosts"
if [[ -d "$BACKUP_DIR" && "$ENV" == "prod" ]]; then
    cp "$OUTPUT_FILE" "$BACKUP_DIR/production.env"
    chmod 600 "$BACKUP_DIR/production.env"
    echo "Backup updated: $BACKUP_DIR/production.env"
fi

echo "Done: $SECRET_COUNT secrets written to $OUTPUT_FILE"
echo ""
echo "To restart containers with new secrets:"
echo "  docker compose -f docker-compose.prod.yml -f docker-compose.external-proxy.yml up -d"
