#!/usr/bin/env bash
#
# Homelab Cluster Bootstrap (Phase 0)
# Bootstrap a fresh Talos cluster to GitOps-ready state (ArgoCD + Forgejo).
# Run once from local checkout, then all future changes via git push.
#
# Prerequisites:
#   - Talos cluster up (terraform apply completed)
#   - kubectl configured (KUBECONFIG points at cluster)
#   - SOPS age key at ~/.sops/homelab-age.key
#   - ArgoCD CLI installed (for final sync)
#
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
K8S_DIR="$SCRIPT_DIR/k8s"
BOOTSTRAP_DIR="$K8S_DIR/bootstrap-local"
SOPS_KEY="${SOPS_KEY:-$HOME/.sops/homelab-age.key}"

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

log() { echo -e "${GREEN}[$(date +'%H:%M:%S')]${NC} $*"; }
warn() { echo -e "${YELLOW}[$(date +'%H:%M:%S')]${NC} $*"; }
error() { echo -e "${RED}[$(date +'%H:%M:%S')]${NC} $*"; exit 1; }

# Preflight checks
log "Running preflight checks..."
kubectl cluster-info > /dev/null || error "kubectl not configured or cluster unreachable"
[[ -f "$SOPS_KEY" ]] || error "SOPS age key not found at $SOPS_KEY"
command -v argocd > /dev/null || warn "ArgoCD CLI not found - manual sync required at end"

# 1. Install ArgoCD itself (if not already present)
if ! kubectl get namespace argocd &>/dev/null; then
    log "Installing ArgoCD..."
    kubectl create namespace argocd
    kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
    log "Waiting for ArgoCD to be ready..."
    kubectl wait --for=condition=available --timeout=300s deployment/argocd-server -n argocd
else
    log "ArgoCD already installed, skipping..."
fi

# 2. Create SOPS age secret (NEVER commit this to git)
log "Creating SOPS age secret..."
kubectl create namespace argocd --dry-run=client -o yaml | kubectl apply -f -
kubectl create secret generic sops-age \
  -n argocd \
  --from-file=keys.txt="$SOPS_KEY" \
  --dry-run=client -o yaml | kubectl apply -f -

# 3. Apply bootstrap bundle (namespaces, CNPG, DDB, Forgejo)
log "Applying bootstrap bundle..."
kubectl apply -k "$BOOTSTRAP_DIR" --server-side

# 4. Wait for CNPG operator
log "Waiting for CNPG operator..."
kubectl wait --for=condition=available --timeout=300s \
  deployment/cnpg-controller-manager -n ddb 2>/dev/null || {
    warn "CNPG operator not found - checking if it exists as different deployment name..."
    kubectl get deployments -n ddb
}

# 5. Wait for DDB cluster
log "Waiting for PostgreSQL cluster (ddb-cluster) to be ready..."
for i in {1..60}; do
    STATUS=$(kubectl get cluster ddb-cluster -n ddb -o jsonpath='{.status.phase}' 2>/dev/null || echo "NotFound")
    if [[ "$STATUS" == "Cluster in healthy state" ]]; then
        log "DDB cluster is ready!"
        break
    fi
    [[ $i -eq 60 ]] && error "Timeout waiting for ddb-cluster"
    sleep 5
done

# 6. Copy DB secret from ddb to cicd namespace
log "Copying ddb-cluster-app secret to cicd namespace..."
kubectl get secret ddb-cluster-app -n ddb -o yaml \
  | sed 's/namespace: ddb/namespace: cicd/' \
  | kubectl apply -f -

# Copy DB secret to iam namespace (for authentik)
log "Copying ddb-cluster-app secret to iam namespace..."
kubectl get secret ddb-cluster-app -n ddb -o yaml \
  | sed 's/namespace: ddb/namespace: iam/' \
  | kubectl apply -f -

# 7. Wait for Forgejo
log "Waiting for Forgejo to be ready..."
kubectl wait --for=condition=available --timeout=600s \
  deployment/forgejo -n cicd 2>/dev/null || {
    warn "Forgejo not found as deployment - checking StatefulSet..."
    kubectl wait --for=condition=available --timeout=600s \
      statefulset/forgejo -n cicd || warn "Could not find Forgejo - check manually"
}

# 8. Apply Longhorn 3-node configuration (if it exists)
if [[ -d "$K8S_DIR/infrastructure/longhorn" ]]; then
    log "Applying Longhorn 3-node HA configuration..."
    kubectl apply -k "$K8S_DIR/infrastructure/longhorn/" || warn "Longhorn config failed - may need manual intervention"
else
    warn "Longhorn config not found at k8s/infrastructure/longhorn/ - storage may be single-node only!"
fi

# 9. Get Forgejo LoadBalancer IP
FORGEJO_IP=$(kubectl get svc forgejo-http -n cicd -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null || echo "unknown")
log "Forgejo available at: http://$FORGEJO_IP:3000 (or https://forgejo.riotpiao.com)"

echo ""
log "${GREEN}========================================${NC}"
log "${GREEN}✅ Bootstrap Complete!${NC}"
log "${GREEN}========================================${NC}"
echo ""
echo "Next steps:"
echo ""
echo "  1. Push this repo to Forgejo:"
echo "     git remote add forgejo https://forgejo.riotpiao.com/riotpiao.com/homelab.git"
echo "     git push forgejo main"
echo ""
echo "  2. Apply app-of-apps root:"
echo "     kubectl apply -k k8s/argocd/root"
echo ""
echo "  3. VERIFY STORAGE REPLICATION (CRITICAL!):"
echo "     See STORAGE-ARCHITECTURE-CLARIFICATION.md"
echo "     kubectl get nodes.longhorn.io -n longhorn-system"
echo "     kubectl get volumes.longhorn.io -n longhorn-system -o wide"
echo ""
echo "  4. Sync all applications:"
echo "     argocd app sync homelab-root"
echo "     # Or via UI: https://argocd.riotpiao.com"
echo ""
echo "  5. All future changes: git commit → git push (ArgoCD auto-syncs)"
echo ""
