name: Rust

on:
  pull_request:
    branches:
      - V3
      - yshekel/V3     # TODO remove when merged to V3
  push:
    branches:
      - V3

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

jobs:
  check-changed-files:
    uses: ./.github/workflows/check-changed-files.yml

  check-format:
    name: Check Code Format
    runs-on: ubuntu-22.04
    needs: check-changed-files
    steps:
    - name: Checkout
      uses: actions/checkout@v4
    - name: Check rustfmt
      if: needs.check-changed-files.outputs.rust == 'true' || needs.check-changed-files.outputs.cpp_cuda == 'true'
      working-directory: ./wrappers/rust
      # "-name target -prune" removes searching in any directory named "target"
      # Formatting by single file is necessary due to generated files not being present
      # before building the project.
      # e.g. icicle-cuda-runtime/src/bindings.rs is generated and icicle-cuda-runtime/src/lib.rs includes that module
      # causing rustfmt to fail.
      run: if [[ $(find . -path ./icicle-curves/icicle-curve-template -prune -o -name target -prune -o -iname *.rs -print | xargs cargo fmt --check --) ]]; then echo "Please run cargo fmt"; exit 1; fi

  extract-cuda-backend-branch:
    name: Extract cuda branch name
    runs-on: ubuntu-22.04
    outputs:
      cuda-backend-branch: ${{ steps.extract.outputs.cuda-backend-branch }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Extract Private Branch from PR Description
        id: extract
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          DESCRIPTION=$(gh pr view ${{ github.event.pull_request.number }} --json body -q '.body')
          echo "PR Description: $DESCRIPTION"
          CUDA_BE_BRANCH=$(echo "$DESCRIPTION" | grep -oP 'cuda-backend-branch:\s*\K[^\s]+') || true
          if [ -z "$CUDA_BE_BRANCH" ]; then
            CUDA_BE_BRANCH="main" # Default branch if not specified
          fi
          echo "Extracted CUDA Backend Branch: $CUDA_BE_BRANCH"
          echo "::set-output name=cuda-backend-branch::$CUDA_BE_BRANCH"

  test-linux:
    name: Test on Linux
    runs-on: [self-hosted, Linux, X64, icicle]
    needs: [check-changed-files, check-format, extract-cuda-backend-branch]
    steps:
    - name: Checkout Repo
      uses: actions/checkout@v4
    - name: Checkout CUDA Backend
      uses: actions/checkout@v4
      with:
        repository: ingonyama-zk/icicle-cuda-backend
        path: ./icicle_v3/backend/cuda
        token: ${{ secrets.GITHUB_TOKEN }}
        ssh-key: ${{ secrets.CUDA_PULL_KEY }}
        ref: ${{ needs.extract-branch.outputs.cuda-backend-branch }}
    - name: Run tests
      working-directory: ./wrappers/rust_v3
      if: needs.check-changed-files.outputs.rust == 'true' || needs.check-changed-files.outputs.cpp_cuda == 'true'
      # tests are split to phases since NTT domain is global but tests have conflicting requirements
      run: |
        cargo build --release --verbose --features=g2,ec_ntt
        cargo test --workspace --release --verbose --features=g2,ec_ntt,cuda_backend -- --skip phase
        cargo test phase2 --workspace --release --verbose --features=g2,ec_ntt,cuda_backend
        cargo test phase3 --workspace --release --verbose --features=g2,ec_ntt,cuda_backend
