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

# runmefirst.sh — Full CI/CD pipeline infrastructure install
# Installs: Gitea config → Woodpecker CI → ArgoCD → Kargo
# Persists state on NFS volumes at nfs://192.168.42.8:/volume1/Kubernetes/pipelines

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

GITEA_AUTH="Authorization: Basic $(echo -n 'admin:St0nks0racl3!' | base64)"
GITEA_API="http://10.1.1.12:30300/api/v1"

# -------------------------------------------------------
# 1. Create namespaces
# -------------------------------------------------------
echo "--- Step 1: Creating namespaces ---"
for ns in woodpecker argocd kargo stonks-beta stonks-paper harbor-service; do
  kubectl create namespace "$ns" --dry-run=client -o yaml | kubectl apply -f -
  echo "  ✓ namespace/$ns"
done
echo ""

# -------------------------------------------------------
# 2. Ensure proxy-ca-cert ConfigMap + Kyverno policies
# -------------------------------------------------------
echo "--- Step 2: Proxy CA cert and Kyverno policies ---"
CA_CERT_PATH="${SCRIPT_DIR}/home.crt"
curl -sf http://192.168.42.1/home.crt -o "$CA_CERT_PATH"
for ns in woodpecker argocd kargo harbor-service; do
  if ! kubectl get configmap proxy-ca-cert -n "$ns" > /dev/null 2>&1; then
    kubectl create configmap proxy-ca-cert --from-file=ca.crt="$CA_CERT_PATH" -n "$ns"
    echo "  ✓ proxy-ca-cert created in $ns"
  else
    echo "  ✓ proxy-ca-cert already exists in $ns"
  fi
done
# Apply Kyverno policy BEFORE Woodpecker install so pods get injected on creation
kubectl apply -f woodpecker/kyverno-proxy-ca.yaml
echo "  ✓ Kyverno woodpecker-proxy-ca policy applied"
# Docker Hub auth for builder pods (avoids rate limits)
if ! kubectl get secret dockerhub-config -n woodpecker > /dev/null 2>&1; then
  kubectl create secret generic dockerhub-config -n woodpecker \
    --from-literal=config.json='{"auths":{"https://index.docker.io/v1/":{"auth":"'"$(echo -n 'celesrenata:dckr_pat_rDJs5PbzGll_jyFyL9_NGEk_bJI' | base64)"'"}}}'
  echo "  ✓ dockerhub-config secret created"
else
  echo "  ✓ dockerhub-config secret already exists"
fi
echo ""

# -------------------------------------------------------
# 3. Apply NFS PersistentVolumes
# -------------------------------------------------------
echo "--- Step 3: Applying NFS PersistentVolumes ---"
kubectl apply -f pvs/argocd-pv.yaml
kubectl apply -f pvs/gitea-pv.yaml
kubectl apply -f pvs/kargo-pv.yaml
kubectl apply -f pvs/woodpecker-pv.yaml
kubectl apply -f pvs/harbor-pv.yaml
echo "  ✓ PVs applied"
echo ""

# -------------------------------------------------------
# 3a. Apply Gitea deployment (NFS-backed)
# -------------------------------------------------------
echo "--- Step 3a: Applying Gitea deployment ---"
kubectl create namespace git-server --dry-run=client -o yaml | kubectl apply -f -
kubectl apply -f gitea/deployment.yaml
kubectl rollout status deployment/gitea -n git-server --timeout=60s
echo "  ✓ Gitea deployed with NFS storage"
echo ""

# -------------------------------------------------------
# 3b. Install Harbor container registry
# -------------------------------------------------------
echo "--- Step 3b: Installing Harbor ---"
kubectl create namespace harbor-service --dry-run=client -o yaml | kubectl apply -f -

# Remove old plain Docker Registry ingress (registry.celestium.life) if it exists
# Harbor will take over that domain
if kubectl get ingress registry-ingress -n git-server > /dev/null 2>&1; then
  echo "  Removing old registry ingress from git-server namespace..."
  kubectl delete ingress registry-ingress -n git-server
  echo "  ✓ Old registry ingress removed"
fi

# Create NFS directories on the NAS (via a temporary pod)
echo "  Ensuring NFS directories exist..."
ssh root@gremlin-1 "
  mkdir -p /tmp/harbor-nfs-init
  mount -t nfs 192.168.42.8:/volume1/Kubernetes/harbor /tmp/harbor-nfs-init 2>/dev/null || true
  mkdir -p /tmp/harbor-nfs-init/data/registry
  mkdir -p /tmp/harbor-nfs-init/data/database
  mkdir -p /tmp/harbor-nfs-init/data/redis
  mkdir -p /tmp/harbor-nfs-init/data/jobservice
  mkdir -p /tmp/harbor-nfs-init/data/trivy
  umount /tmp/harbor-nfs-init 2>/dev/null || true
  rmdir /tmp/harbor-nfs-init 2>/dev/null || true
" 2>/dev/null || echo "  ⚠ Could not create NFS dirs via SSH (non-fatal, they may already exist)"

# Apply PVCs
kubectl apply -f harbor/pvcs.yaml
echo "  ✓ Harbor PVCs applied"

# Install/upgrade Harbor via Helm
helm repo add harbor https://helm.goharbor.io 2>/dev/null || true
helm repo update harbor 2>/dev/null || true

HARBOR_EXISTS=$(helm list -n harbor-service -q 2>/dev/null | grep -c harbor || true)
if [ "${HARBOR_EXISTS:-0}" -gt 0 ]; then
  echo "  Harbor already installed — upgrading..."
else
  echo "  Fresh Harbor install..."
fi

helm upgrade --install harbor harbor/harbor \
  --namespace harbor-service \
  --values harbor/values.yaml \
  --timeout 10m \
  --wait

echo "  Waiting for Harbor core to be ready..."
kubectl wait --for=condition=ready pod -l app=harbor,component=core -n harbor-service --timeout=180s > /dev/null 2>&1 || true
echo "  ✓ Harbor installed at https://registry.celestium.life"
echo "    Default login: admin / St0nks0racl3!"
echo ""

# -------------------------------------------------------
# 4. Configure Gitea (admin user, repo, webhook config)
# -------------------------------------------------------
echo "--- Step 4: Configuring Gitea ---"
bash gitea/setup.sh
echo "  ✓ Gitea configured"

GITEA_POD=$(kubectl get pods -n git-server -l app=gitea -o jsonpath='{.items[0].metadata.name}')
if ! kubectl exec -n git-server "$GITEA_POD" -- grep -q '\[webhook\]' /data/gitea/conf/app.ini 2>/dev/null; then
  kubectl exec -n git-server "$GITEA_POD" -- sh -c 'printf "\n[webhook]\nALLOWED_HOST_LIST = *\nSKIP_TLS_VERIFY = true\n" >> /data/gitea/conf/app.ini'
  kubectl rollout restart deployment/gitea -n git-server
  kubectl rollout status deployment/gitea -n git-server --timeout=60s
  echo "  ✓ Gitea webhook config added"
else
  echo "  ✓ Gitea webhook config already present"
fi
echo ""

# -------------------------------------------------------
# 5. Install Woodpecker CI via Helm
# -------------------------------------------------------
echo "--- Step 5: Installing Woodpecker CI ---"

WOODPECKER_EXISTS=$(helm list -n woodpecker -q 2>/dev/null | grep -c woodpecker || true)

if [ "${WOODPECKER_EXISTS:-0}" -gt 0 ]; then
  echo "  Woodpecker already installed — upgrading..."
  helm upgrade woodpecker oci://ghcr.io/woodpecker-ci/helm/woodpecker \
    --namespace woodpecker \
    --values woodpecker/values.yaml \
    --timeout 5m
else
  echo "  Fresh Woodpecker install..."
  # Delete stale OAuth2 app in Gitea (if any) and create fresh one
  # only if the values.yaml still has placeholders
  CURRENT_CLIENT=$(grep WOODPECKER_GITEA_CLIENT woodpecker/values.yaml | head -1 | awk -F'"' '{print $2}')
  if [ "$CURRENT_CLIENT" = "<GITEA_CLIENT_ID>" ] || [ -z "$CURRENT_CLIENT" ]; then
    EXISTING_APP_ID=$(curl -s -H "$GITEA_AUTH" "$GITEA_API/user/applications/oauth2" | python3 -c '
import sys, json
for app in json.loads(sys.stdin.read()):
    if app.get("name") == "woodpecker-ci":
        print(app["id"])
        break
' 2>/dev/null || echo "")
    if [ -n "$EXISTING_APP_ID" ]; then
      curl -s -X DELETE -H "$GITEA_AUTH" "$GITEA_API/user/applications/oauth2/$EXISTING_APP_ID" > /dev/null
      echo "  Deleted stale OAuth2 app (id=$EXISTING_APP_ID)"
    fi
    OAUTH2_RESP=$(curl -s -X POST "$GITEA_API/user/applications/oauth2" \
      -H "$GITEA_AUTH" -H "Content-Type: application/json" \
      -d '{"name":"woodpecker-ci","redirect_uris":["https://stonks-ci.celestium.life/authorize"],"confidential_client":true}')
    GITEA_CLIENT_ID=$(echo "$OAUTH2_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['client_id'])")
    GITEA_CLIENT_SECRET=$(echo "$OAUTH2_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['client_secret'])")
    echo "  ✓ OAuth2 app created (client_id: $GITEA_CLIENT_ID)"

    helm install woodpecker oci://ghcr.io/woodpecker-ci/helm/woodpecker \
      --namespace woodpecker \
      --values woodpecker/values.yaml \
      --set server.env.WOODPECKER_GITEA_CLIENT="${GITEA_CLIENT_ID}" \
      --set server.env.WOODPECKER_GITEA_SECRET="${GITEA_CLIENT_SECRET}" \
      --timeout 5m
  else
    echo "  ✓ OAuth2 creds baked into values.yaml — using those"
    helm install woodpecker oci://ghcr.io/woodpecker-ci/helm/woodpecker \
      --namespace woodpecker \
      --values woodpecker/values.yaml \
      --timeout 5m
  fi
fi

# Wait for server to be ready (don't use --wait, agents may take longer)
echo "  Waiting for Woodpecker server..."
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=server -n woodpecker --timeout=120s > /dev/null 2>&1 || true
echo "  Waiting for Woodpecker agents..."
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=agent -n woodpecker --timeout=120s > /dev/null 2>&1 || true

# Apply agent RBAC (grants cluster-admin to default + woodpecker-agent SAs)
kubectl apply -f woodpecker/agent-rbac.yaml
echo "  ✓ Woodpecker CI installed + RBAC applied"

# -------------------------------------------------------
# 5b. Activate repo in Woodpecker (if fresh install)
# -------------------------------------------------------
if [ "${WOODPECKER_EXISTS:-0}" -eq 0 ]; then
  echo "  Activating repo in Woodpecker..."
  # Wait for server to be ready
  kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=server -n woodpecker --timeout=60s > /dev/null 2>&1

  # Port-forward to Woodpecker API
  kubectl port-forward -n woodpecker svc/woodpecker-server 18080:80 > /dev/null 2>&1 &
  PF_PID=$!
  sleep 5

  # Login via OAuth2 to get a user token — use the Gitea token approach
  # Create a Gitea personal access token for API bootstrap
  GITEA_TOKEN_RESP=$(curl -s -X POST "$GITEA_API/users/admin/tokens" \
    -H "$GITEA_AUTH" -H "Content-Type: application/json" \
    -d '{"name":"woodpecker-bootstrap-'"$(date +%s)"'","scopes":["all"]}')
  GITEA_PAT=$(echo "$GITEA_TOKEN_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['sha1'])")

  # Use Woodpecker's OAuth2 flow to get a session — this is complex via CLI
  # Instead, just tell the user to activate via UI on first install
  echo "  ⚠ First install: please log in to https://stonks-ci.celestium.life"
  echo "    1. Activate the admin/stonks-oracle repo"
  echo "    2. Mark it as trusted (Settings → General → Trusted)"
  echo "    3. Add 'github_ssh_key' secret (Settings → Secrets)"

  kill $PF_PID 2>/dev/null || true
  wait $PF_PID 2>/dev/null || true

  # Fix webhook to internal URL after user activates
  echo "  After activating, run: bash pipelines/fix-webhook.sh"
fi
echo ""

# -------------------------------------------------------
# 6. Install ArgoCD via Helm
# -------------------------------------------------------
echo "--- Step 6: Installing ArgoCD ---"
ARGOCD_EXISTS=$(helm list -n argocd -q 2>/dev/null | grep -c argocd || true)
if [ "${ARGOCD_EXISTS:-0}" -eq 0 ]; then
  kubectl delete crd applications.argoproj.io applicationsets.argoproj.io appprojects.argoproj.io \
    --ignore-not-found --timeout=30s > /dev/null 2>&1 || true
  kubectl delete sa --all -n argocd --ignore-not-found --timeout=10s > /dev/null 2>&1 || true
  kubectl delete role --all -n argocd --ignore-not-found --timeout=10s > /dev/null 2>&1 || true
  kubectl delete rolebinding --all -n argocd --ignore-not-found --timeout=10s > /dev/null 2>&1 || true
fi
helm repo add argo https://argoproj.github.io/argo-helm || true
helm repo update
helm upgrade --install argocd argo/argo-cd \
  --namespace argocd \
  --values argocd/values.yaml \
  --wait --timeout 5m
echo "  ✓ ArgoCD installed"

kubectl apply -f argocd/repo-secret.yaml
kubectl apply -f argocd/apps/stonks-beta.yaml
kubectl apply -f argocd/apps/stonks-paper.yaml
kubectl apply -f argocd/apps/stonks-live.yaml
echo "  ✓ ArgoCD repo secret and Applications applied"
echo ""

# -------------------------------------------------------
# 6b. Install Argo Rollouts (CRDs + controller for Kargo verification)
# -------------------------------------------------------
echo "--- Step 6b: Installing Argo Rollouts ---"
kubectl create namespace argo-rollouts --dry-run=client -o yaml | kubectl apply -f -
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
kubectl rollout status deployment/argo-rollouts -n argo-rollouts --timeout=120s > /dev/null 2>&1 || true
echo "  ✓ Argo Rollouts installed (provides AnalysisRun CRD for Kargo verification)"
echo ""

# -------------------------------------------------------
# 6c. Seed secrets for beta, paper, and live namespaces
# -------------------------------------------------------
echo "--- Step 6c: Seeding secrets for beta/paper/live ---"
# These secrets are NOT managed by Helm (ArgoCD ignoreDifferences prevents overwrite).
# Source credentials from the cluster's infrastructure services.
REDIS_PW=$(kubectl get secret -n redis-service redis -o jsonpath='{.data.redis-password}' | base64 -d 2>/dev/null || echo "")
MINIO_AK=$(kubectl get secret -n minio-service minio-secrets -o jsonpath='{.data.MINIO_ACCESS_KEY}' | base64 -d 2>/dev/null || echo "minioadmin")
MINIO_SK=$(kubectl get secret -n minio-service minio-secrets -o jsonpath='{.data.MINIO_SECRET_KEY}' | base64 -d 2>/dev/null || echo "minioadmin")
ALPACA_KEY=$(cat /root/sources/celesrenata/stonks-oracle/alpaca.key 2>/dev/null || echo "")
ALPACA_SECRET=$(cat /root/sources/celesrenata/stonks-oracle/alpaca.secret 2>/dev/null || echo "")
ALPACA_URL=$(cat /root/sources/celesrenata/stonks-oracle/alpaca.url 2>/dev/null || echo "https://paper-api.alpaca.markets")
POLYGON_KEY=$(cat /root/sources/celesrenata/stonks-oracle/polygon.io.key 2>/dev/null || echo "")

for ns in stonks-beta stonks-paper stonks-oracle; do
  # Determine the correct Postgres user for this namespace
  case "$ns" in
    stonks-beta)  PG_USER="stonks_beta" ;;
    stonks-paper) PG_USER="stonks_paper" ;;
    *)            PG_USER="stonks" ;;
  esac
  kubectl create secret generic stonks-core-secrets \
    --from-literal=POSTGRES_PASSWORD='St0nks0racl3!' \
    --from-literal=REDIS_PASSWORD="$REDIS_PW" \
    --from-literal=MINIO_ACCESS_KEY="$MINIO_AK" \
    --from-literal=MINIO_SECRET_KEY="$MINIO_SK" \
    -n "$ns" --dry-run=client -o yaml | kubectl apply -f -
  kubectl create secret generic stonks-broker-secrets \
    --from-literal=BROKER_API_KEY="$ALPACA_KEY" \
    --from-literal=BROKER_API_SECRET="$ALPACA_SECRET" \
    --from-literal=BROKER_BASE_URL="$ALPACA_URL" \
    -n "$ns" --dry-run=client -o yaml | kubectl apply -f -
  kubectl create secret generic stonks-market-secrets \
    --from-literal=MARKET_DATA_API_KEY="$POLYGON_KEY" \
    -n "$ns" --dry-run=client -o yaml | kubectl apply -f -
  kubectl create secret generic stonks-gmail-secrets \
    --from-literal=GMAIL_SENDER='celes@celestium.life' \
    --from-literal=GMAIL_RECIPIENT='celes@celestium.life' \
    --from-literal=GMAIL_APP_PASSWORD='' \
    -n "$ns" --dry-run=client -o yaml | kubectl apply -f -
  kubectl create secret generic stonks-dashboard-secrets \
    --from-literal=SUPERSET_SECRET_KEY='stonks-superset-key' \
    --from-literal=SUPERSET_ADMIN_PASSWORD='St0nks0racl3!' \
    -n "$ns" --dry-run=client -o yaml | kubectl apply -f -
  echo "  ✓ Secrets seeded in $ns"
done
echo ""

# -------------------------------------------------------
# 6d. Create isolated databases for beta and paper stages
# -------------------------------------------------------
echo "--- Step 6d: Creating stage-isolated databases ---"
PG_POD=$(kubectl get pods -n postgresql-service -l cnpg.io/cluster=postgresql,role=primary -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "postgresql-1")

# Create databases and per-stage users (idempotent)
for pair in "stonks_beta:stonks_beta" "stonks_paper:stonks_paper"; do
  DB="${pair%%:*}"
  USER="${pair##*:}"
  kubectl exec -i -n postgresql-service "$PG_POD" -c postgres -- psql -U postgres << SQL
DO \$\$ BEGIN
  IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '$USER') THEN
    CREATE USER $USER WITH PASSWORD 'St0nks0racl3!';
  END IF;
END \$\$;
SELECT 'CREATE DATABASE $DB OWNER $USER' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname='$DB')\gexec
GRANT ALL PRIVILEGES ON DATABASE $DB TO $USER;
SQL
  # Ensure schema permissions
  kubectl exec -i -n postgresql-service "$PG_POD" -c postgres -- psql -U postgres -d "$DB" << SQL
GRANT ALL ON SCHEMA public TO $USER;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO $USER;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO $USER;
SQL
  echo "  ✓ Database $DB with user $USER"
done

# Live DB stays as 'stonks' user (already exists)
kubectl exec -i -n postgresql-service "$PG_POD" -c postgres -- \
  psql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname='stonks'" | grep -q 1 || \
  kubectl exec -i -n postgresql-service "$PG_POD" -c postgres -- \
    psql -U postgres -c "CREATE DATABASE stonks OWNER stonks;"
echo "  ✓ Database stonks with user stonks"

# Run migrations on all three databases as their respective users
REPO_ROOT="${SCRIPT_DIR}/../stonks-oracle"
if [ -d "$REPO_ROOT/infra/migrations" ]; then
  for pair in "stonks:stonks" "stonks_beta:stonks_beta" "stonks_paper:stonks_paper"; do
    DB="${pair%%:*}"
    USER="${pair##*:}"
    echo "  Running migrations on $DB as $USER..."
    for migration in $(ls "$REPO_ROOT/infra/migrations/"*.sql 2>/dev/null | sort); do
      kubectl exec -i -n postgresql-service "$PG_POD" -c postgres -- \
        psql -U "$USER" -d "$DB" < "$migration" > /dev/null 2>&1 || true
    done
    echo "  ✓ Migrations applied to $DB"
  done
else
  echo "  ⚠ Migrations directory not found at $REPO_ROOT/infra/migrations — skipping"
fi

# Seed symbol registry data on all three databases
if [ -d "$REPO_ROOT/services/symbol_registry" ]; then
  for pair in "stonks:stonks" "stonks_beta:stonks_beta" "stonks_paper:stonks_paper"; do
    DB="${pair%%:*}"
    USER="${pair##*:}"
    echo "  Seeding $DB..."
    POSTGRES_HOST=postgresql-rw.postgresql-service.svc.cluster.local \
    POSTGRES_PASSWORD='St0nks0racl3!' POSTGRES_USER="$USER" POSTGRES_DB="$DB" \
    python3 -m services.symbol_registry.seed 2>/dev/null || true
    echo "  ✓ Seed data applied to $DB"
  done
fi
echo ""

# -------------------------------------------------------
# 7. Install Kargo via Helm
# -------------------------------------------------------
echo "--- Step 7: Installing Kargo ---"
KARGO_EXISTS=$(helm list -n kargo -q 2>/dev/null | grep -c kargo || true)
if [ "${KARGO_EXISTS:-0}" -eq 0 ]; then
  kubectl delete crd freights.kargo.akuity.io projects.kargo.akuity.io stages.kargo.akuity.io \
    warehouses.kargo.akuity.io promotions.kargo.akuity.io promotiontasks.kargo.akuity.io \
    clusterpromotiontasks.kargo.akuity.io projectconfigs.kargo.akuity.io \
    clusterconfigs.kargo.akuity.io --ignore-not-found --timeout=30s > /dev/null 2>&1 || true
  kubectl delete sa --all -n kargo --ignore-not-found --timeout=10s > /dev/null 2>&1 || true
  kubectl delete role --all -n kargo --ignore-not-found --timeout=10s > /dev/null 2>&1 || true
  kubectl delete rolebinding --all -n kargo --ignore-not-found --timeout=10s > /dev/null 2>&1 || true
fi
# Kargo chart bug: controller deployment references SA 'kargo-controller' but chart doesn't create it
# Pre-create with Helm labels so it doesn't conflict with the chart
kubectl apply -f - <<'SAEOF'
apiVersion: v1
kind: ServiceAccount
metadata:
  name: kargo-controller
  namespace: kargo
  labels:
    app.kubernetes.io/managed-by: Helm
  annotations:
    meta.helm.sh/release-name: kargo
    meta.helm.sh/release-namespace: kargo
SAEOF
helm upgrade --install kargo oci://ghcr.io/akuity/kargo-charts/kargo \
  --namespace kargo \
  --values kargo/values.yaml \
  --timeout 5m || true
echo "  Waiting for kargo-controller..."
for i in $(seq 1 24); do
  if kubectl get pods -n kargo -l app.kubernetes.io/component=controller -o jsonpath='{.items[0].status.containerStatuses[0].ready}' 2>/dev/null | grep -q true; then
    break
  fi
  kubectl delete pod -n kargo -l app.kubernetes.io/component=controller --field-selector=status.phase=Failed --ignore-not-found > /dev/null 2>&1 || true
  sleep 5
done
echo "  ✓ Kargo installed"

# Fix Kargo admin password — Helm chart leaves the secret empty on fresh install.
# The hash must match the password in kargo/values.yaml (passwordHash field).
KARGO_PW_HASH='$2b$10$juNdw96VeP/7oP3.RYPnwuUo2lk/eheAqkUqbwh16a1UH17olxyWC'
kubectl get secret kargo-api -n kargo -o json | \
  python3 -c "
import sys, json, base64
d = json.load(sys.stdin)
d['data']['ADMIN_ACCOUNT_PASSWORD_HASH'] = base64.b64encode(b'${KARGO_PW_HASH}').decode()
for k in ['managedFields','resourceVersion','uid','creationTimestamp']:
    d['metadata'].pop(k, None)
json.dump(d, sys.stdout)
" | kubectl replace -f - > /dev/null 2>&1 || true
kubectl delete pod -n kargo -l app.kubernetes.io/component=api --ignore-not-found > /dev/null 2>&1
echo "  ✓ Kargo admin password configured (admin / St0nksKarg0!)"

kubectl apply -f kargo/project.yaml
kubectl apply -f kargo/project-config.yaml
kubectl apply -f kargo/warehouse.yaml
kubectl apply -f kargo/market-hours-check.yaml
kubectl apply -f kargo/stages/beta.yaml
kubectl apply -f kargo/stages/paper.yaml
kubectl apply -f kargo/stages/live.yaml
echo "  ✓ Kargo project, warehouse, and stages applied"
echo ""

echo "=== Pipeline Infrastructure Install Complete ==="
echo ""
echo "Endpoints:"
echo "  Harbor:        https://registry.celestium.life"
echo "  Woodpecker CI: https://stonks-ci.celestium.life"
echo "  ArgoCD:        https://stonks-argocd.celestium.life"
echo "  Kargo:         https://stonks-kargo.celestium.life"
