name: GoLang

on:
  pull_request:
    branches:
      - main
      - dev
  push:
    branches:
      - main
      - dev

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: Setup go
      uses: actions/setup-go@v5
      with:
        go-version: '1.20.0'
    - name: Check gofmt
      if: needs.check-changed-files.outputs.golang == 'true'
      run: if [[ $(go list ./... | xargs go fmt) ]]; then echo "Please run go fmt"; exit 1; fi

  build-linux:
    name: Build on Linux
    runs-on: [self-hosted, Linux, X64, icicle]
    needs: [check-changed-files, check-format]
    strategy:
      matrix:
        curve: [bn254, bls12_381, bls12_377, bw6_761]
    steps:
    - name: Checkout Repo
      uses: actions/checkout@v4
    - name: Setup go
      uses: actions/setup-go@v5
      with:
        go-version: '1.20.0'
    - name: Build
      working-directory: ./wrappers/golang
      if: needs.check-changed-files.outputs.golang == 'true' || needs.check-changed-files.outputs.cpp_cuda == 'true'
      run: ./build.sh ${{ matrix.curve }} ON # builds a single curve with G2 enabled
    - name: Upload ICICLE lib artifacts
      uses: actions/upload-artifact@v4
      if: needs.check-changed-files.outputs.golang == 'true' || needs.check-changed-files.outputs.cpp_cuda == 'true'
      with:
        name: icicle-builds-${{ matrix.curve }}-${{ github.workflow }}-${{ github.sha }}
        path: icicle/build/libingo_${{ matrix.curve }}.a
        retention-days: 1
  
  test-linux:
    name: Test on Linux
    runs-on: [self-hosted, Linux, X64, icicle]
    needs: [check-changed-files, build-linux]
    steps:
    - name: Checkout Repo
      uses: actions/checkout@v4
    - name: Setup go
      uses: actions/setup-go@v5
      with:
        go-version: '1.20.0'
    - name: Download ICICLE lib artifacts
      uses: actions/download-artifact@v4
      if: needs.check-changed-files.outputs.golang == 'true' || needs.check-changed-files.outputs.cpp_cuda == 'true'
      with:
        path: ./icicle/build/
        merge-multiple: true
    - name: Run Tests
      working-directory: ./wrappers/golang
      if: needs.check-changed-files.outputs.golang == 'true' || needs.check-changed-files.outputs.cpp_cuda == 'true'
      # -count ensures the test results are not cached
      # -p controls the number of programs that can be run in parallel
      run: |
        export CPATH=$CPATH:/usr/local/cuda/include
        go test --tags=g2 ./... -count=1 -failfast -p 2 -timeout 60m
  
  # TODO: bw6 on windows requires more memory than the standard runner has
  # Add a large runner and then enable this job
  # build-windows:
  #   name: Build on Windows
  #   runs-on: windows-2022
  #   needs: [check-changed-files, check-format]
  #   strategy:
  #     matrix:
  #       curve: [bn254, bls12_381, bls12_377, bw6_761]
  #   steps:     
  #   - name: Checkout Repo
  #     uses: actions/checkout@v4
  #   - name: Setup go
  #     uses: actions/setup-go@v5
  #     with:
  #       go-version: '1.20.0'
  #   - name: Download and Install Cuda
  #     if: needs.check-changed-files.outputs.golang == 'true' || needs.check-changed-files.outputs.cpp_cuda == 'true'
  #     id: cuda-toolkit
  #     uses: Jimver/cuda-toolkit@v0.2.11
  #     with:
  #       cuda: '12.0.0'
  #       method: 'network'
  #       # https://docs.nvidia.com/cuda/archive/12.0.0/cuda-installation-guide-microsoft-windows/index.html
  #       sub-packages: '["cudart", "nvcc", "thrust", "visual_studio_integration"]'
  #   - name: Build libs
  #     if: needs.check-changed-files.outputs.golang == 'true' || needs.check-changed-files.outputs.cpp_cuda == 'true'
  #     working-directory: ./wrappers/golang
  #     env:
  #       CUDA_PATH: ${{ steps.cuda-toolkit.outputs.CUDA_PATH }}
  #     shell: pwsh
  #     run: ./build.ps1 ${{ matrix.curve }} ON # builds a single curve with G2 enabled
