name: CI/CD Pipeline

on:
  push:
    branches:
      - development
      - main

jobs:
  build-app:
    name: Build and Push App Docker Image
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set environment variables
        run: |
          if [ "${{ github.ref }}" == "refs/heads/main" ]; then
            echo "DOCKER_TAG=latest" >> $GITHUB_ENV
            echo "ENVIRONMENT=prod" >> $GITHUB_ENV
          else
            echo "DOCKER_TAG=dev" >> $GITHUB_ENV
            echo "ENVIRONMENT=dev" >> $GITHUB_ENV
          fi

      - name: Build and push app Docker image
        run: |
          docker login git.yohler.net -u ${{ github.actor }} -p ${{ secrets.PACKAGES_TOKEN }}

          docker build \
            -f Dockerfile \
            -t git.yohler.net/kyle/flxn-app:${{ env.DOCKER_TAG }} \
            -t git.yohler.net/kyle/flxn-app:${{ github.sha }} \
            .

          docker push git.yohler.net/kyle/flxn-app:${{ env.DOCKER_TAG }}
          docker push git.yohler.net/kyle/flxn-app:${{ github.sha }}

  build-pocketbase:
    name: Build and Push PocketBase Docker Image
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Check if PocketBase Dockerfile or migrations changed
        id: check_changes
        run: |
          if [ "${{ github.event.before }}" == "0000000000000000000000000000000000000000" ] || ! git cat-file -e ${{ github.event.before }} 2>/dev/null; then
            echo "changed=true" >> $GITHUB_OUTPUT
          elif git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep -qE "(Dockerfile.pocketbase|pb_migrations/)"; then
            echo "changed=true" >> $GITHUB_OUTPUT
          else
            echo "changed=false" >> $GITHUB_OUTPUT
          fi

      - name: Build and push PocketBase Docker image
        if: steps.check_changes.outputs.changed == 'true' || github.event.before == '0000000000000000000000000000000000000000'
        run: |
          docker login git.yohler.net -u ${{ github.actor }} -p ${{ secrets.PACKAGES_TOKEN }}

          docker build \
            -f Dockerfile.pocketbase \
            -t git.yohler.net/kyle/flxn-pocketbase:latest \
            -t git.yohler.net/kyle/flxn-pocketbase:${{ github.sha }} \
            .

          docker push git.yohler.net/kyle/flxn-pocketbase:latest
          docker push git.yohler.net/kyle/flxn-pocketbase:${{ github.sha }}

  deploy:
    name: Deploy to Kubernetes
    needs: [build-app, build-pocketbase]
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set environment variables
        run: |
          if [ "${{ github.ref }}" == "refs/heads/main" ]; then
            echo "ENVIRONMENT=prod" >> $GITHUB_ENV
            echo "NAMESPACE=flxn-prod" >> $GITHUB_ENV
          else
            echo "ENVIRONMENT=dev" >> $GITHUB_ENV
            echo "NAMESPACE=flxn-dev" >> $GITHUB_ENV
          fi

      - name: Install kubectl
        run: |
          curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
          chmod +x kubectl
          mv kubectl /usr/local/bin/

      - name: Configure kubectl
        run: |
          mkdir -p $HOME/.kube
          echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > $HOME/.kube/config
          chmod 600 $HOME/.kube/config
          kubectl config set-cluster local --insecure-skip-tls-verify=true

      - name: Verify kubectl access
        run: |
          kubectl version --client
          kubectl get nodes

      - name: Deploy shared services (SuperTokens)
        run: |
          kubectl apply -k k8s/overlays/shared/

      - name: Deploy to ${{ env.ENVIRONMENT }}
        run: |
          kubectl apply -k k8s/overlays/${{ env.ENVIRONMENT }}/

      - name: Force rollout to pull latest image
        run: |
          kubectl rollout restart deployment/flxn-app -n ${{ env.NAMESPACE }}
          kubectl rollout restart deployment/flxn-pocketbase -n ${{ env.NAMESPACE }}

      - name: Wait for rollout
        run: |
          kubectl rollout status deployment/flxn-app -n ${{ env.NAMESPACE }} --timeout=5m
          kubectl rollout status deployment/flxn-pocketbase -n ${{ env.NAMESPACE }} --timeout=5m

      - name: Verify deployment
        run: |
          kubectl get pods -n ${{ env.NAMESPACE }} -l app=flxn
          kubectl get svc -n ${{ env.NAMESPACE }} -l app=flxn
          kubectl get ingress -n ${{ env.NAMESPACE }}

      - name: Check app health
        run: |
          sleep 15
          APP_POD=$(kubectl get pod -n ${{ env.NAMESPACE }} -l component=app -o jsonpath='{.items[0].metadata.name}')
          kubectl exec -n ${{ env.NAMESPACE }} $APP_POD -- wget -O- http://localhost:3000/api/health || echo "Health check failed (endpoint may not exist yet)"

      - name: Check PocketBase health
        run: |
          PB_POD=$(kubectl get pod -n ${{ env.NAMESPACE }} -l component=pocketbase -o jsonpath='{.items[0].metadata.name}')
          kubectl exec -n ${{ env.NAMESPACE }} $PB_POD -- wget -O- http://localhost:8090/api/health || echo "PocketBase health check completed"
