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

NAMESPACE="stonks-oracle"
REPO_DIR="$HOME/sources/celesrenata/stonks-oracle"
CHART_DIR="$REPO_DIR/infra/helm/stonks-oracle"
MIGRATIONS_DIR="$REPO_DIR/infra/migrations"
KUBE_DIR="$HOME/sources/kube/stonks-oracle"

# --- Secrets ---
# All secrets are read from ~/sources/kube/stonks-oracle/ on gremlin-1.
# This directory is NOT a git repo — secrets stay local to the deploy host.
#
# Required files:
#   ~/sources/kube/stonks-oracle/polygon.io.key
#   ~/sources/kube/stonks-oracle/alpaca.key
#   ~/sources/kube/stonks-oracle/alpaca.secret
#   ~/sources/kube/stonks-oracle/alpaca.url
#   /run/secrets/github_token

_read_secret() {
  local file="$1"
  local default="${2:-}"
  if [ -f "$file" ]; then
    cat "$file" | tr -d '[:space:]'
  elif [ -n "$default" ]; then
    echo "$default"
  else
    echo "ERROR: Secret file not found: $file" >&2
    exit 1
  fi
}

GHCR_TOKEN=$(_read_secret /run/secrets/github_token)
PG_PASSWORD='St0nks0racl3!'
REDIS_PASSWORD='PSCh4ng3me!'
MINIO_ACCESS_KEY="AKIA6V7J3N9B5P0D2YQH"
MINIO_SECRET_KEY='8fG3!v2rJ7$wN@9mLpQ6zXbC4tKdPqW1'
POLYGON_API_KEY=$(_read_secret "$KUBE_DIR/polygon.io.key")
ALPACA_API_KEY=$(_read_secret "$KUBE_DIR/alpaca.key")
ALPACA_API_SECRET=$(_read_secret "$KUBE_DIR/alpaca.secret")
ALPACA_BASE_URL=$(_read_secret "$KUBE_DIR/alpaca.url" "https://paper-api.alpaca.markets")
GMAIL_APP_PASSWORD=$(_read_secret "$KUBE_DIR/gmail.app" "")

echo "=== Stonks Oracle Deployment ==="
echo "Namespace: $NAMESPACE"
echo "Chart:     $CHART_DIR"
echo "Secrets:   $KUBE_DIR"

# --- 0. Pull latest code ---
echo "[0/5] Pulling latest code..."
git -C "$REPO_DIR" pull --ff-only || echo "WARNING: git pull failed — using existing code"

# --- 1. Ensure namespace exists with correct labels ---
echo "[1/5] Ensuring namespace $NAMESPACE exists..."
if ! kubectl get namespace "$NAMESPACE" >/dev/null 2>&1; then
  kubectl create namespace "$NAMESPACE"
fi
kubectl label namespace "$NAMESPACE" app.kubernetes.io/managed-by=Helm --overwrite
kubectl annotate namespace "$NAMESPACE" meta.helm.sh/release-name=stonks-oracle meta.helm.sh/release-namespace=stonks-oracle --overwrite

# --- 2. Create PostgreSQL user and database ---
echo "[2/5] Setting up PostgreSQL database and user..."
kubectl exec -i -n postgresql-service postgresql-1 -c postgres -- psql -U postgres <<EOF
DO \$\$
BEGIN
  IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'stonks') THEN
    CREATE USER stonks WITH PASSWORD '$PG_PASSWORD';
  ELSE
    ALTER USER stonks WITH PASSWORD '$PG_PASSWORD';
  END IF;
END
\$\$;

SELECT 'CREATE DATABASE stonks OWNER stonks'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'stonks')\gexec

GRANT ALL PRIVILEGES ON DATABASE stonks TO stonks;
EOF

# --- 3. Run migrations ---
echo "[3/5] Running database migrations..."
for f in $(ls "$MIGRATIONS_DIR"/*.sql | sort); do
  echo "  -> $(basename "$f")"
  kubectl exec -i -n postgresql-service postgresql-1 -c postgres -- psql -U postgres -d stonks < "$f" 2>&1 | grep -v "already exists" || true
done

# Grant permissions
kubectl exec -i -n postgresql-service postgresql-1 -c postgres -- psql -U postgres -d stonks <<EOF
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO stonks;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO stonks;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO stonks;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO stonks;
EOF

# --- 4. Helm deploy ---
echo "[4/5] Deploying via Helm..."

# Verify GHCR token can pull images (repo may be private)
echo "  Verifying GHCR credentials..."
if ! echo "$GHCR_TOKEN" | docker login ghcr.io -u celesrenata --password-stdin >/dev/null 2>&1; then
  echo "WARNING: GHCR login failed — token may be expired or missing scopes."
  echo "  Ensure /run/secrets/github_token has 'read:packages' scope."
  echo "  Generate a new token at: https://github.com/settings/tokens"
  echo "  Continuing anyway (Helm will create the secret, but pods may fail to pull)..."
fi

# Force-recreate the GHCR pull secret to ensure it's fresh
kubectl delete secret ghcr-credentials -n "$NAMESPACE" --ignore-not-found
kubectl create secret docker-registry ghcr-credentials \
  --namespace "$NAMESPACE" \
  --docker-server=ghcr.io \
  --docker-username=celesrenata \
  --docker-password="$GHCR_TOKEN" \
  --dry-run=client -o yaml | kubectl apply -f -

helm upgrade --install stonks-oracle "$CHART_DIR" \
  --namespace "$NAMESPACE" \
  --set "ghcrAuth.password=$GHCR_TOKEN" \
  --set "secrets.core.POSTGRES_PASSWORD=$PG_PASSWORD" \
  --set "secrets.core.MINIO_ACCESS_KEY=$MINIO_ACCESS_KEY" \
  --set "secrets.core.MINIO_SECRET_KEY=$MINIO_SECRET_KEY" \
  --set "secrets.core.REDIS_PASSWORD=$REDIS_PASSWORD" \
  --set "secrets.market.MARKET_DATA_API_KEY=$POLYGON_API_KEY" \
  --set "secrets.broker.BROKER_API_KEY=$ALPACA_API_KEY" \
  --set "secrets.broker.BROKER_API_SECRET=$ALPACA_API_SECRET" \
  --set "secrets.broker.BROKER_BASE_URL=$ALPACA_BASE_URL" \
  --set "secrets.gmail.GMAIL_APP_PASSWORD=$GMAIL_APP_PASSWORD"

# --- 5. Rolling restart to pick up new images ---
echo "[5/5] Rolling restart..."
for dep in $(kubectl get deployments -n "$NAMESPACE" -o name); do
  kubectl rollout restart -n "$NAMESPACE" "$dep"
done

echo ""
echo "=== Deployment complete ==="
echo "Waiting for pods..."
sleep 10
kubectl get pods -n "$NAMESPACE" -o custom-columns='NAME:.metadata.name,READY:.status.containerStatuses[0].ready,STATUS:.status.phase,RESTARTS:.status.containerStatuses[0].restartCount'
echo ""
echo "Ingress endpoints:"
kubectl get ingress -n "$NAMESPACE" -o custom-columns='HOST:.spec.rules[0].host,ADDRESS:.status.loadBalancer.ingress[0].ip'
