name: Deploy to Azure AKS

on:
  push:
    branches:
      - main
      - production
  workflow_dispatch:
    inputs:
      environment:
        description: 'Environment to deploy to'
        required: true
        type: choice
        options:
          - staging
          - production
        default: staging

env:
  REGISTRY: mylaravelregistry.azurecr.io
  IMAGE_NAME: laravel-app
  TERRAFORM_VERSION: 1.9.0

jobs:
  build-and-push:
    name: Build and Push Docker Image
    runs-on: ubuntu-latest
    outputs:
      image_tag: ${{ steps.meta.outputs.tags }}

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to Azure Container Registry
        uses: azure/docker-login@v1
        with:
          login-server: ${{ env.REGISTRY }}
          username: ${{ secrets.ACR_USERNAME }}
          password: ${{ secrets.ACR_PASSWORD }}

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=ref,event=branch
            type=sha,prefix={{branch}}-
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}

      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ./Dockerfile
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
          cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max

  terraform-deploy:
    name: Terraform Deploy
    runs-on: ubuntu-latest
    needs: build-and-push
    environment: ${{ github.event.inputs.environment || 'staging' }}

    defaults:
      run:
        working-directory: terraform

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: ${{ env.TERRAFORM_VERSION }}

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

      - name: Create terraform.tfvars
        run: |
          cat > terraform.tfvars <<EOF
          subscription_id = "${{ secrets.AZURE_SUBSCRIPTION_ID }}"
          resource_group_name = "trusted_ai_demo_rg"
          location = "germanywestcentral"
          aks_cluster_name = "trai_k8s_cluster"

          app_name = "laravel-app"
          app_namespace = "laravel-app"
          app_env = "${{ github.event.inputs.environment || 'staging' }}"
          app_debug = ${{ github.event.inputs.environment == 'production' && 'false' || 'true' }}
          app_replicas = ${{ github.event.inputs.environment == 'production' && '3' || '2' }}

          docker_image = "${{ needs.build-and-push.outputs.image_tag }}"
          app_key = "${{ secrets.LARAVEL_APP_KEY }}"

          postgresql_admin_username = "${{ secrets.POSTGRESQL_ADMIN_USERNAME }}"
          postgresql_admin_password = "${{ secrets.POSTGRESQL_ADMIN_PASSWORD }}"
          postgresql_sku_name = "${{ github.event.inputs.environment == 'production' && 'GP_Standard_D2s_v3' || 'B_Standard_B1ms' }}"
          postgresql_storage_mb = ${{ github.event.inputs.environment == 'production' && '131072' || '32768' }}

          ingress_enabled = true
          ingress_host = "${{ secrets.INGRESS_HOST }}"

          ssl_enabled = ${{ github.event.inputs.environment == 'production' && 'true' || 'false' }}
          ssl_issuer_email = "${{ secrets.SSL_ISSUER_EMAIL }}"

          db_restore_enabled = false

          alert_email_address = "${{ secrets.ALERT_EMAIL }}"
          EOF

      - name: Terraform Init
        run: terraform init

      - name: Terraform Validate
        run: terraform validate

      - name: Terraform Plan
        run: terraform plan -out=tfplan

      - name: Terraform Apply
        if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/production'
        run: terraform apply -auto-approve tfplan

      - name: Get kubectl credentials
        if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/production'
        run: |
          az aks get-credentials \
            --resource-group trusted_ai_demo_rg \
            --name trai_k8s_cluster \
            --overwrite-existing

      - name: Wait for deployment
        if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/production'
        run: |
          kubectl wait --for=condition=ready pod \
            -l app=laravel-app \
            -n laravel-app \
            --timeout=300s || true

      - name: Get Application URL
        if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/production'
        id: get-url
        run: |
          APP_URL=$(terraform output -raw app_url)
          echo "url=$APP_URL" >> $GITHUB_OUTPUT
          echo "### Deployment Complete! 🚀" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "Application URL: $APP_URL" >> $GITHUB_STEP_SUMMARY

      - name: Upload Terraform Plan
        if: github.ref != 'refs/heads/main' && github.ref != 'refs/heads/production'
        uses: actions/upload-artifact@v4
        with:
          name: terraform-plan
          path: terraform/tfplan

  smoke-tests:
    name: Smoke Tests
    runs-on: ubuntu-latest
    needs: terraform-deploy
    if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/production'

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

      - name: Get kubectl credentials
        run: |
          az aks get-credentials \
            --resource-group trusted_ai_demo_rg \
            --name trai_k8s_cluster \
            --overwrite-existing

      - name: Check pod health
        run: |
          kubectl get pods -n laravel-app
          READY_PODS=$(kubectl get pods -n laravel-app -l app=laravel-app -o jsonpath='{.items[*].status.conditions[?(@.type=="Ready")].status}' | grep -o "True" | wc -l)
          if [ "$READY_PODS" -lt 1 ]; then
            echo "Error: No ready pods found"
            exit 1
          fi
          echo "✓ $READY_PODS pod(s) are ready"

      - name: Check service endpoint
        run: |
          LOADBALANCER_IP=$(kubectl get svc ingress-nginx-controller -n ingress-nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
          if [ -z "$LOADBALANCER_IP" ]; then
            echo "Warning: LoadBalancer IP not yet assigned"
          else
            echo "✓ LoadBalancer IP: $LOADBALANCER_IP"

            # Try to reach the application
            HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://$LOADBALANCER_IP --max-time 10)
            if [ "$HTTP_CODE" -eq 200 ] || [ "$HTTP_CODE" -eq 302 ]; then
              echo "✓ Application is responding (HTTP $HTTP_CODE)"
            else
              echo "Warning: Application returned HTTP $HTTP_CODE"
            fi
          fi

      - name: Check database connectivity
        run: |
          DB_SECRET=$(kubectl get secret laravel-app-db-credentials -n laravel-app -o jsonpath='{.data.DB_HOST}' | base64 -d)
          echo "✓ Database host configured: $DB_SECRET"

  notify:
    name: Notify Deployment Status
    runs-on: ubuntu-latest
    needs: [build-and-push, terraform-deploy, smoke-tests]
    if: always()

    steps:
      - name: Deployment Success
        if: ${{ needs.terraform-deploy.result == 'success' && needs.smoke-tests.result == 'success' }}
        run: |
          echo "### ✅ Deployment Successful!" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "Environment: ${{ github.event.inputs.environment || 'staging' }}" >> $GITHUB_STEP_SUMMARY
          echo "Commit: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY

      - name: Deployment Failed
        if: ${{ needs.terraform-deploy.result == 'failure' || needs.smoke-tests.result == 'failure' }}
        run: |
          echo "### ❌ Deployment Failed!" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "Please check the logs for details." >> $GITHUB_STEP_SUMMARY
          exit 1
