name: CD - Development Build

on:
  pull_request:
    branches: [ 'rc', 'rc/**' ]
    # Only trigger builds when actual code changes
    # This uses explicit paths to skip documentation, markdown, and other non-code changes
    paths:
      - 'app/**'
      - 'migrations/**'
      - 'requirements*.txt'
      - 'setup.py'
      - 'Dockerfile'
      - 'docker-compose*.yml'
      - 'package*.json'
      - 'tailwind.config.js'
      - 'postcss.config.js'
      - '.github/workflows/cd-development.yml'
      - 'babel.cfg'
      - 'pytest.ini'
      - 'Makefile'
  workflow_dispatch:
    inputs:
      force_build:
        description: 'Force build even if tests fail'
        required: false
        type: boolean
        default: false
      create_release:
        description: 'Create GitHub release (default: false for regular builds)'
        required: false
        type: boolean
        default: false

# Concurrency control: cancel in-progress builds when new commits are pushed
# This prevents wasting resources on outdated builds
concurrency:
  group: dev-build-${{ github.ref }}
  cancel-in-progress: true

# Required permissions for creating releases and pushing images
permissions: write-all

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}
  PYTHON_VERSION: '3.11'

jobs:
  # ============================================================================
  # Quick Test Suite for Development
  # ============================================================================
  quick-tests:
    name: Quick Test Suite
    runs-on: ubuntu-latest
    timeout-minutes: 20
    
    services:
      postgres:
        image: postgres:16-alpine
        env:
          POSTGRES_PASSWORD: test_password
          POSTGRES_USER: test_user
          POSTGRES_DB: test_db
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
      
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: ${{ env.PYTHON_VERSION }}
          cache: 'pip'
      
      - name: Install dependencies
        run: |
          pip install -r requirements.txt
          pip install -r requirements-test.txt
          pip install -e .
      
      - name: Run smoke tests
        env:
          PYTHONPATH: ${{ github.workspace }}
        run: |
          pytest -m smoke -v --tb=short --no-cov -n auto
      
      - name: Validate database migrations
        env:
          DATABASE_URL: postgresql://test_user:test_password@localhost:5432/test_db
          FLASK_APP: app.py
          FLASK_ENV: testing
        run: |
          echo "🔍 Validating database migrations..."
          
          # Check if there are migration-related changes
          if git diff --name-only HEAD~1 2>/dev/null | grep -E "(app/models/|migrations/)" > /dev/null; then
            echo "📋 Migration-related changes detected"
            
            # Initialize fresh database
            flask db upgrade
            
            # Test migration rollback
            CURRENT_MIGRATION=$(flask db current)
            echo "Current migration: $CURRENT_MIGRATION"
            
            if [ -n "$CURRENT_MIGRATION" ] && [ "$CURRENT_MIGRATION" != "None" ]; then
              echo "Testing migration operations..."
              flask db upgrade head
              echo "✅ Migration validation passed"
            fi
          else
            echo "ℹ️ No migration-related changes detected"
          fi

  # ============================================================================
  # Build and Push Development Image
  # ============================================================================
  build-and-push:
    name: Build and Push Development Image
    runs-on: ubuntu-latest
    needs: quick-tests
    if: always() && (needs.quick-tests.result == 'success' || github.event.inputs.force_build == 'true')
    timeout-minutes: 30
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
      
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      
      - name: Log in to Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      
      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=raw,value=develop
            type=raw,value=dev-{{date 'YYYYMMDD-HHmmss'}}
            type=sha,prefix=dev-,format=short
          labels: |
            org.opencontainers.image.description=Self-hosted time tracking web application for projects, clients, and reports.
      
      - name: Determine version
        id: version
        run: |
          BUILD_NUMBER=${{ github.run_number }}
          COMMIT_SHA=${GITHUB_SHA::8}
          VERSION="dev-${BUILD_NUMBER}-${COMMIT_SHA}"
          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "📦 Building version: $VERSION"
      
      - name: Inject donate-hide public key (optional)
        env:
          DONATE_HIDE_PUBLIC_KEY_PEM: ${{ secrets.DONATE_HIDE_PUBLIC_KEY_PEM }}
        run: |
          if [ -n "$DONATE_HIDE_PUBLIC_KEY_PEM" ]; then
            echo "✅ DONATE_HIDE_PUBLIC_KEY_PEM set — writing donate_hide_public.pem for Docker build"
            echo "$DONATE_HIDE_PUBLIC_KEY_PEM" > donate_hide_public.pem
          else
            echo "⚠️  DONATE_HIDE_PUBLIC_KEY_PEM not set — Support visibility verification disabled in image"
          fi
      
      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          build-args: |
            APP_VERSION=${{ steps.version.outputs.version }}
          cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop
          cache-to: type=inline
      
      - name: Generate deployment manifest
        run: |
          cat > deployment-dev.yml << EOF
          # TimeTracker Development Deployment
          # Generated: $(date -u +'%Y-%m-%d %H:%M:%S UTC')
          # Version: ${{ steps.version.outputs.version }}
          # Commit: ${{ github.sha }}
          
          version: '3.8'
          
          services:
            app:
              image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop
              container_name: timetracker-dev
              ports:
                - "8080:8080"
              environment:
                - TZ=Europe/Brussels
                - DATABASE_URL=postgresql://timetracker:timetracker@db:5432/timetracker
                - SECRET_KEY=\${SECRET_KEY}
                - FLASK_ENV=development
                - APP_VERSION=${{ steps.version.outputs.version }}
              depends_on:
                - db
              restart: unless-stopped
            
            db:
              image: postgres:16-alpine
              container_name: timetracker-dev-db
              environment:
                - POSTGRES_DB=timetracker
                - POSTGRES_USER=timetracker
                - POSTGRES_PASSWORD=\${POSTGRES_PASSWORD}
              volumes:
                - db_data:/var/lib/postgresql/data
              restart: unless-stopped
          
          volumes:
            db_data:
          EOF
          
          echo "📄 Deployment manifest created"
          cat deployment-dev.yml
      
      - name: Upload deployment manifest
        uses: actions/upload-artifact@v4
        with:
          name: deployment-manifest-dev
          path: deployment-dev.yml
      
      - name: Create GitHub Release (Development)
        # Only create releases when explicitly requested via workflow_dispatch
        # This prevents cluttering the releases page with every dev build
        if: github.event_name == 'workflow_dispatch' && github.event.inputs.create_release == 'true'
        continue-on-error: true
        uses: actions/github-script@v7
        with:
          script: |
            const version = '${{ steps.version.outputs.version }}';
            const tagName = `dev-${version}`;
            
            try {
              await github.rest.repos.createRelease({
                owner: context.repo.owner,
                repo: context.repo.repo,
                tag_name: tagName,
                name: `Development Build ${version}`,
                body: `## Development Build
                
                **Version:** ${version}
                **Commit:** ${context.sha.substring(0, 7)}
                **PR:** #${{ github.event.pull_request.number }}
                **Target Branch:** ${{ github.base_ref }}
                **Build:** #${context.runNumber}
                
                ### Docker Image
                \`\`\`
                ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop
                \`\`\`
                
                ### Quick Start
                \`\`\`bash
                docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop
                docker-compose -f deployment-dev.yml up -d
                \`\`\`
                
                ### Changes
                ${context.payload.head_commit?.message || 'See commit history'}
                
                ---
                *This is a manually triggered development build.*
                `,
                draft: false,
                prerelease: true
              });
              
              console.log('✅ Development release created');
            } catch (error) {
              if (error.status === 422) {
                console.log('⚠️ Release already exists, skipping');
              } else if (error.status === 403) {
                console.log('⚠️ GitHub Actions does not have permission to create releases');
                console.log('📝 To fix: Go to Settings → Actions → General → Workflow permissions');
                console.log('📝 Select "Read and write permissions" and save');
              } else {
                throw error;
              }
            }

  # ============================================================================
  # Notification
  # ============================================================================
  notify:
    name: Send Notifications
    runs-on: ubuntu-latest
    needs: [quick-tests, build-and-push]
    if: always()
    
    steps:
      - name: Determine build status
        id: status
        run: |
          if [ "${{ needs.build-and-push.result }}" == "success" ]; then
            echo "status=✅ Success" >> $GITHUB_OUTPUT
            echo "color=28a745" >> $GITHUB_OUTPUT
          else
            echo "status=❌ Failed" >> $GITHUB_OUTPUT
            echo "color=dc3545" >> $GITHUB_OUTPUT
          fi
      
      - name: Create summary
        run: |
          echo "## 🚀 Development Build ${{ steps.status.outputs.status }}" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "**Target Branch:** ${{ github.base_ref }}" >> $GITHUB_STEP_SUMMARY
          echo "**Source Branch:** ${{ github.head_ref }}" >> $GITHUB_STEP_SUMMARY
          echo "**Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
          echo "**Build:** #${{ github.run_number }}" >> $GITHUB_STEP_SUMMARY
          echo "**Trigger:** ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "### Test Results" >> $GITHUB_STEP_SUMMARY
          echo "- Tests: ${{ needs.quick-tests.result }}" >> $GITHUB_STEP_SUMMARY
          echo "- Build: ${{ needs.build-and-push.result }}" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          
          if [ "${{ needs.build-and-push.result }}" == "success" ]; then
            echo "### 🐳 Docker Image" >> $GITHUB_STEP_SUMMARY
            echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
            echo "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop" >> $GITHUB_STEP_SUMMARY
            echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
            echo "" >> $GITHUB_STEP_SUMMARY
            
            # Note about release creation
            if [ "${{ github.event_name }}" == "workflow_dispatch" ] && [ "${{ github.event.inputs.create_release }}" == "true" ]; then
              echo "📦 GitHub release created" >> $GITHUB_STEP_SUMMARY
            else
              echo "ℹ️ No GitHub release created (use workflow_dispatch with create_release=true to create one)" >> $GITHUB_STEP_SUMMARY
            fi
          fi
          
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "---" >> $GITHUB_STEP_SUMMARY
          echo "💡 **Tip:** This workflow runs on PRs to RC branches. Documentation and test-only changes are skipped." >> $GITHUB_STEP_SUMMARY

