name: Checks

on:
  pull_request: {}
  push: { branches: [main] }

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: actions-rs/toolchain@v1
        with: { toolchain: stable }
      - uses: Swatinem/rust-cache@v2
        with:
          shared-key: build
      - uses: actions-rs/cargo@v1
        with: { command: build, args: --locked --workspace }
      
  benchmark:
    needs: build
    name: Benchmark
    runs-on: ubuntu-latest

    concurrency:
      group: checks-${{ github.ref }}
      cancel-in-progress: true

    steps:
      - uses: actions/checkout@v5
      - name: Install FFMpeg
        uses: FedericoCarboni/setup-ffmpeg@v3
      - uses: actions-rs/toolchain@v1
        with: { toolchain: stable }
      - uses: Swatinem/rust-cache@v2
        with:
          shared-key: build
      - uses: extractions/setup-just@v3
      - uses: carlosperate/download-file-action@v2
        with:
          file-url: "https://gwennlbh.github.io/shapemaker/timings.csv"
          file-name: results-main.csv
      - run: just timings results-main.csv
      - id: video
        uses: actions/upload-artifact@v5
        with:
          name: output-video
          path: out.mp4
          if-no-files-found: error
          compression-level: 0
          overwrite: true
      - id: results_csv
        uses: juliangruber/read-file-action@v1
        with: { path: ./results.csv }
      - id: results_table
        uses: petems/csv-to-md-table-action@master
        with: { csvinput: "${{ steps.results_csv.outputs.content }}" }
      - name: Comment on PR
        if: github.event_name == 'pull_request'
        # create or update a comment on the PR with the results
        uses: edumserrano/find-create-or-update-comment@v3
        with:
          issue-number: ${{ github.event.pull_request.number }}
          edit-mode: replace
          body-includes: <!-- PERF TIMING RESULTS COMMENT -->
          body: |
            <!-- PERF TIMING RESULTS COMMENT -->
            ### Performance Timings

            ${{ steps.results_table.outputs.markdown-table }}

            ### Resulting video

            ${{ steps.video.outputs.artifact-url }}

  check:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - name: Install FFMpeg
        uses: FedericoCarboni/setup-ffmpeg@v3
      - uses: actions-rs/toolchain@v1
        with: { toolchain: stable }
      - uses: Swatinem/rust-cache@v2
        with:
          shared-key: check
      - uses: actions-rs/cargo@v1
        with: { command: check, args: --locked --workspace }
      - uses: actions-rs/cargo@v1
        with: { command: check, args: --locked --no-default-features --features web }

  test:
    needs: build
    name: Test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - name: Install FFMpeg
        uses: FedericoCarboni/setup-ffmpeg@v3
      - uses: actions-rs/toolchain@v1
        with: { toolchain: stable }
      - uses: Swatinem/rust-cache@v2
        with:
          shared-key: build
      - uses: actions-rs/cargo@v1
        with: { command: test, args: --workspace }

  video-baseline-update:
    if: github.event_name == 'push'
    needs: build
    name: Update baseline test video
    runs-on: ubuntu-latest
    concurrency:
      group: video-test-update-baseline-${{ github.ref_name }}
      cancel-in-progress: true
    permissions:
      contents: write
    defaults:
      run:
        working-directory: ./examples/schedule-hell
    steps:
      - uses: actions/checkout@v5
        with: 
          ssh-key: ${{ secrets.AUTOCOMMIT_KEY }}
      - name: Install FFMpeg
        uses: FedericoCarboni/setup-ffmpeg@v3
      - name: Install VMAF
        uses: ethanjli/cached-download-action@v0.1.3
        with:
          url: https://github.com/Netflix/vmaf/releases/download/v3.0.0/vmaf
          destination: /usr/local/bin/vmaf
      - run: chmod +x /usr/local/bin/vmaf
      - uses: actions-rs/toolchain@v1
        with: { toolchain: stable }
      - uses: Swatinem/rust-cache@v2
        with:
          shared-key: build
      - run: mv baseline.mp4 old-baseline.mp4
      - run: cargo run -- --duration 10 baseline.mp4
      - name: Convert to yuv4mpeg
        run: |
          for f in $files; do
            ffmpeg -i $f -f yuv4mpegpipe -y $(basename $f .mp4).y4m
          done
        env:
          files: old-baseline.mp4 baseline.mp4
      - name: Run VMAF
        run: vmaf --json --output comparison.json
          --reference old-baseline.y4m
          --distorted baseline.y4m
      - name: Judge score
        id: results
        run: |
          score=$(jq .pooled_metrics.vmaf.mean comparison.json)

          if (( $(echo "$score < 95" | bc -l) )); then
            conclusion=changed
          else
            conclusion=unchanged
          fi

          echo "score=$score" >> $GITHUB_OUTPUT
          echo "conclusion=$conclusion" >> $GITHUB_OUTPUT

      - if: steps.results.outputs.conclusion == 'changed'
        name: Commit changes
        uses: stefanzweifel/git-auto-commit-action@v7
        with:
          commit_message: ✅ Update video test baseline
          file_pattern: examples/schedule-hell/baseline.mp4

  video:
    if: github.event_name == 'pull_request'
    needs: build
    name: Video
    runs-on: ubuntu-latest
    permissions:
      checks: write
      contents: read
    concurrency:
      group: video-test-${{ github.ref_name }}
      cancel-in-progress: true
    defaults:
      run:
        working-directory: ./examples/schedule-hell
    steps: 
      - uses: actions/checkout@v5
      - name: Install FFMpeg
        uses: FedericoCarboni/setup-ffmpeg@v3
      - name: Install VMAF
        uses: ethanjli/cached-download-action@v0.1.3
        with:
          url: https://github.com/Netflix/vmaf/releases/download/v3.0.0/vmaf
          destination: /usr/local/bin/vmaf
      - run: chmod +x /usr/local/bin/vmaf
      - uses: actions-rs/toolchain@v1
        with: { toolchain: stable }
      - uses: Swatinem/rust-cache@v2
        with:
          shared-key: build
      - uses: extractions/setup-just@v3
      - run: cargo run --locked -- --duration 10 result.mp4
      - name: Convert to yuv4mpeg
        run: |
          for f in $files; do
            ffmpeg -i $f -f yuv4mpegpipe -y $(basename $f .mp4).y4m
          done
        env:
          files: baseline.mp4 result.mp4

      - name: Compare with VMAF
        run: vmaf --json 
          --output comparison.json 
          --reference baseline.y4m 
          --distorted result.y4m

      - name: Judge score
        id: results
        run: |
          score=$(jq .pooled_metrics.vmaf.mean comparison.json)

          if (( $(echo "$score < 95" | bc -l) )); then
            conclusion=failure
            comparison_display="$score < 95"
          else
            conclusion=success
            comparison_display="$score ≥ 95"
          fi

          echo "score=$score" >> $GITHUB_OUTPUT
          echo "conclusion=$conclusion" >> $GITHUB_OUTPUT
          echo "comparison_display=$comparison_display" >> $GITHUB_OUTPUT

      - name: Upload comparison artifacts
        uses: actions/upload-artifact@v5
        id: artifacts
        with:
          path: |
            examples/schedule-hell/comparison.json
            examples/schedule-hell/baseline.mp4
            examples/schedule-hell/result.mp4

      - uses: LouisBrunner/checks-action@v2
        with:
          name: Compare to baseline test video
          token: ${{ secrets.GITHUB_TOKEN }}
          conclusion: ${{ steps.results.outputs.conclusion }}
          output: |
            {
              "title": "VMAF Score is ${{ steps.results.outputs.comparison_display }}",
              "summary": "Artifacts available at ${{ steps.artifacts.outputs.artifact-url }}"
            }

      - name: Fail if score too low
        if: steps.results.outputs.conclusion == 'failure'
        run: exit 1
