name: Benchmark

on:
  workflow_dispatch:
    inputs:
      frameworks:
        description: 'Frameworks to benchmark (space-separated, default: all)'
        required: false
        default: ''

jobs:
  bench:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    defaults:
      run:
        shell: bash
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          driver-opts: network=host

      - name: Determine frameworks to build
        id: frameworks
        run: |
          if [ -n "${{ github.event.inputs.frameworks }}" ]; then
            echo "list=${{ github.event.inputs.frameworks }}" >> $GITHUB_OUTPUT
          else
            echo "list=nextjs solidjs leptos dioxus jetzig ziex" >> $GITHUB_OUTPUT
          fi

      - name: Build nextjs
        if: contains(steps.frameworks.outputs.list, 'nextjs')
        uses: docker/build-push-action@v6
        with:
          context: bench/nextjs
          load: true
          tags: ziex_bench-nextjs:latest
          cache-from: type=gha,scope=nextjs
          cache-to: type=gha,mode=max,scope=nextjs

      - name: Build solidjs
        if: contains(steps.frameworks.outputs.list, 'solidjs')
        uses: docker/build-push-action@v6
        with:
          context: bench/solidjs
          load: true
          tags: ziex_bench-solidjs:latest
          cache-from: type=gha,scope=solidjs
          cache-to: type=gha,mode=max,scope=solidjs

      - name: Build leptos
        if: contains(steps.frameworks.outputs.list, 'leptos')
        uses: docker/build-push-action@v6
        with:
          context: bench/leptos
          load: true
          tags: ziex_bench-leptos:latest
          cache-from: type=gha,scope=leptos
          cache-to: type=gha,mode=max,scope=leptos

      - name: Build dioxus
        if: contains(steps.frameworks.outputs.list, 'dioxus')
        uses: docker/build-push-action@v6
        with:
          context: bench/dioxus
          load: true
          tags: ziex_bench-dioxus:latest
          cache-from: type=gha,scope=dioxus
          cache-to: type=gha,mode=max,scope=dioxus

      - name: Build ziex
        if: contains(steps.frameworks.outputs.list, 'ziex')
        uses: docker/build-push-action@v6
        with:
          context: .
          file: bench/ziex/Dockerfile
          load: true
          tags: ziex_bench-ziex:latest
          cache-from: type=gha,scope=ziex
          cache-to: type=gha,mode=max,scope=ziex

      - name: Build jetzig
        if: contains(steps.frameworks.outputs.list, 'jetzig')
        uses: docker/build-push-action@v6
        with:
          context: bench/jetzig
          load: true
          tags: ziex_bench-jetzig:latest
          cache-from: type=gha,scope=jetzig
          cache-to: type=gha,mode=max,scope=jetzig

      - name: Build bench
        uses: docker/build-push-action@v6
        with:
          context: bench
          file: bench/Dockerfile.bench
          load: true
          tags: ziex_bench-bench:latest
          cache-from: type=gha,scope=bench
          cache-to: type=gha,mode=max,scope=bench

      - name: Run benchmark script
        id: bench
        working-directory: bench
        run: |
          chmod +x run.sh
          if [ -n "${{ github.event.inputs.frameworks }}" ]; then
            ./run.sh ${{ github.event.inputs.frameworks }}
          else
            ./run.sh
          fi
        env:
          DOCKER_BUILDKIT: 1

      - name: Upload result.csv artifact
        uses: actions/upload-artifact@v4
        with:
          name: bench-results
          path: bench/result.csv

      - name: Print result.csv to GitHub output
        id: print-result
        run: |
          echo 'Benchmark Results:'
          cat bench/result.csv
          echo "results<<EOF" >> $GITHUB_OUTPUT
          cat bench/result.csv >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: Print summary
        run: |
          {
            echo "## Benchmark Results"
            echo ""
            echo "| Framework | Req/s | P50 (ms) | P99 (ms) | Idle (MB) | Peak (MB) | Image (MB) | Binary (MB) | Cold Start (ms) | Avg CPU (%) | Peak CPU (%) | Build (s) |"
            echo "|-----------|------:|---------:|---------:|----------:|----------:|-----------:|------------:|----------------:|------------:|-------------:|----------:|"
            tail -n +2 bench/result.csv | while IFS=',' read -r fw idle peak build_time img_mb bin_mb cold_ms cpu_avg cpu_peak rps p50 p99; do
              case "$fw" in
                ziex) label="Ziex" ;;
                jetzig) label="Jetzig" ;;
                leptos) label="Leptos" ;;
                dioxus) label="Dioxus" ;;
                solidjs) label="SolidStart" ;;
                nextjs) label="Next.js" ;;
                *) label="$fw" ;;
              esac
              printf "| %s | %.0f | %.2f | %.2f | %.1f | %.1f | %.0f | %s | %.0f | %.1f | %.1f | %.0f |\n" \
                "$label" "$rps" "$p50" "$p99" "$idle" "$peak" "$img_mb" "$bin_mb" "$cold_ms" "$cpu_avg" "$cpu_peak" "$build_time"
            done
          } >> $GITHUB_STEP_SUMMARY
