name: Backend CI/CD Pipeline

on:
  push:
    branches:
      - develop
      - main
    paths:
      - '*-service/**'
      - '.github/workflows/backend-cicd.yaml'
      - '.github/kustomize/**'
  pull_request:
    branches:
      - develop
      - main
    paths:
      - '*-service/**'
  workflow_dispatch:
    inputs:
      environment:
        description: 'Target environment'
        required: true
        type: choice
        options:
          - dev
          - staging
          - prod
      service:
        description: 'Service to deploy (all for all services)'
        required: true
        default: 'all'

env:
  ACR_NAME: acrdigitalgarage01
  RESOURCE_GROUP: rg-digitalgarage-01
  AKS_CLUSTER: aks-digitalgarage-01
  NAMESPACE: kt-event-marketing
  JDK_VERSION: '21'

jobs:
  detect-changes:
    name: Detect Changed Services
    runs-on: ubuntu-latest
    outputs:
      services: ${{ steps.detect.outputs.services }}
      environment: ${{ steps.env.outputs.environment }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Determine environment
        id: env
        run: |
          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
            echo "environment=${{ github.event.inputs.environment }}" >> $GITHUB_OUTPUT
          elif [ "${{ github.ref }}" = "refs/heads/main" ]; then
            echo "environment=prod" >> $GITHUB_OUTPUT
          elif [ "${{ github.ref }}" = "refs/heads/develop" ]; then
            echo "environment=dev" >> $GITHUB_OUTPUT
          else
            echo "environment=dev" >> $GITHUB_OUTPUT
          fi

      - name: Detect changed services
        id: detect
        run: |
          if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ github.event.inputs.service }}" != "all" ]; then
            echo "services=[\"${{ github.event.inputs.service }}\"]" >> $GITHUB_OUTPUT
          elif [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ github.event.inputs.service }}" = "all" ]; then
            echo "services=[\"user-service\",\"event-service\",\"ai-service\",\"content-service\",\"distribution-service\",\"participation-service\",\"analytics-service\"]" >> $GITHUB_OUTPUT
          else
            CHANGED_SERVICES=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }} | \
              grep -E '^(user|event|ai|content|distribution|participation|analytics)-service/' | \
              cut -d'/' -f1 | sort -u | \
              jq -R -s -c 'split("\n") | map(select(length > 0))')

            if [ "$CHANGED_SERVICES" = "[]" ] || [ -z "$CHANGED_SERVICES" ]; then
              echo "services=[\"user-service\",\"event-service\",\"ai-service\",\"content-service\",\"distribution-service\",\"participation-service\",\"analytics-service\"]" >> $GITHUB_OUTPUT
            else
              echo "services=$CHANGED_SERVICES" >> $GITHUB_OUTPUT
            fi
          fi

  build-and-push:
    name: Build and Push - ${{ matrix.service }}
    needs: detect-changes
    runs-on: ubuntu-latest
    strategy:
      matrix:
        service: ${{ fromJson(needs.detect-changes.outputs.services) }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up JDK ${{ env.JDK_VERSION }}
        uses: actions/setup-java@v4
        with:
          java-version: ${{ env.JDK_VERSION }}
          distribution: 'temurin'
          cache: 'gradle'

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Build with Gradle
        run: ./gradlew ${{ matrix.service }}:build -x test

      # - name: Run tests
      #   run: ./gradlew ${{ matrix.service }}:test

      - name: Build JAR
        run: ./gradlew ${{ matrix.service }}:bootJar

      - name: Log in to Azure Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.ACR_NAME }}.azurecr.io
          username: ${{ secrets.ACR_USERNAME }}
          password: ${{ secrets.ACR_PASSWORD }}

      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: ./${{ matrix.service }}
          file: ./${{ matrix.service }}/Dockerfile
          push: true
          tags: |
            ${{ env.ACR_NAME }}.azurecr.io/kt-event-marketing/${{ matrix.service }}:${{ needs.detect-changes.outputs.environment }}
            ${{ env.ACR_NAME }}.azurecr.io/kt-event-marketing/${{ matrix.service }}:${{ github.sha }}
            ${{ env.ACR_NAME }}.azurecr.io/kt-event-marketing/${{ matrix.service }}:latest

  deploy:
    name: Deploy to AKS - ${{ needs.detect-changes.outputs.environment }}
    needs: [detect-changes, build-and-push]
    runs-on: ubuntu-latest
    environment: ${{ needs.detect-changes.outputs.environment }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Azure login
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: Get AKS credentials
        run: |
          az aks get-credentials \
            --resource-group ${{ env.RESOURCE_GROUP }} \
            --name ${{ env.AKS_CLUSTER }} \
            --overwrite-existing

      - name: Setup Kustomize
        uses: imranismail/setup-kustomize@v2

      - name: Deploy with Kustomize
        run: |
          cd .github/kustomize/overlays/${{ needs.detect-changes.outputs.environment }}
          kustomize edit set image \
            acrdigitalgarage01.azurecr.io/kt-event-marketing/user-service:${{ needs.detect-changes.outputs.environment }} \
            acrdigitalgarage01.azurecr.io/kt-event-marketing/event-service:${{ needs.detect-changes.outputs.environment }} \
            acrdigitalgarage01.azurecr.io/kt-event-marketing/ai-service:${{ needs.detect-changes.outputs.environment }} \
            acrdigitalgarage01.azurecr.io/kt-event-marketing/content-service:${{ needs.detect-changes.outputs.environment }} \
            acrdigitalgarage01.azurecr.io/kt-event-marketing/distribution-service:${{ needs.detect-changes.outputs.environment }} \
            acrdigitalgarage01.azurecr.io/kt-event-marketing/participation-service:${{ needs.detect-changes.outputs.environment }} \
            acrdigitalgarage01.azurecr.io/kt-event-marketing/analytics-service:${{ needs.detect-changes.outputs.environment }}

          kustomize build . | kubectl apply -f -

      - name: Wait for deployment rollout
        run: |
          for service in $(echo '${{ needs.detect-changes.outputs.services }}' | jq -r '.[]'); do
            echo "Waiting for ${service} deployment..."
            kubectl rollout status deployment/${service} -n ${{ env.NAMESPACE }} --timeout=5m
          done

      - name: Verify deployment
        run: |
          echo "=== Pods Status ==="
          kubectl get pods -n ${{ env.NAMESPACE }} -l app.kubernetes.io/part-of=kt-event-marketing

          echo "=== Services ==="
          kubectl get svc -n ${{ env.NAMESPACE }}

          echo "=== Ingress ==="
          kubectl get ingress -n ${{ env.NAMESPACE }}

  notify:
    name: Notify Deployment Result
    needs: [detect-changes, deploy]
    runs-on: ubuntu-latest
    if: always()
    steps:
      - name: Deployment Success
        if: needs.deploy.result == 'success'
        run: |
          echo "✅ Deployment to ${{ needs.detect-changes.outputs.environment }} succeeded!"
          echo "Services: ${{ needs.detect-changes.outputs.services }}"

      - name: Deployment Failure
        if: needs.deploy.result == 'failure'
        run: |
          echo "❌ Deployment to ${{ needs.detect-changes.outputs.environment }} failed!"
          echo "Services: ${{ needs.detect-changes.outputs.services }}"
          exit 1
