name: GoLang

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

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-curves-linux:
    name: Build and test curves on Linux
    runs-on: [self-hosted, Linux, X64, icicle]
    needs: [check-changed-files, check-format]
    strategy:
      matrix:
        curve: 
          - name: bn254
            build_args: -g2 -ecntt
          - name: bls12_381
            build_args: -g2 -ecntt
          - name: bls12_377
            build_args: -g2 -ecntt
          - name: bw6_761
            build_args: -g2 -ecntt
          - name: grumpkin
            build_args:
    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'
      # builds a single curve with the curve's specified build args
      run: ./build.sh -curve=${{ matrix.curve.name }} ${{ matrix.curve.build_args }}
    - name: Test
      working-directory: ./wrappers/golang/curves
      if: needs.check-changed-files.outputs.golang == 'true' || needs.check-changed-files.outputs.cpp_cuda == 'true'
      run: |
        CURVE=$(echo ${{ matrix.curve.name }} | sed -e 's/_//g')
        export CPATH=$CPATH:/usr/local/cuda/include
        go test ./$CURVE/tests -count=1 -failfast -p 2 -timeout 60m -v
 
  build-fields-linux:
    name: Build and test fields on Linux
    runs-on: [self-hosted, Linux, X64, icicle]
    needs: [check-changed-files, check-format]
    strategy:
      matrix:
        field:
          - name: babybear
            build_args: -field-ext
    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'
      # builds a single field with the fields specified build args
      run: ./build.sh -field=${{ matrix.field.name }} ${{ matrix.field.build_args }}
    - name: Test
      working-directory: ./wrappers/golang/fields
      if: needs.check-changed-files.outputs.golang == 'true' || needs.check-changed-files.outputs.cpp_cuda == 'true'
      run: |
        FIELD=$(echo ${{ matrix.field.name }} | sed -e 's/_//g')
        export CPATH=$CPATH:/usr/local/cuda/include
        go test ./$FIELD/tests -count=1 -failfast -p 2 -timeout 60m -v
    
  build-hashes-linux:
    name: Build and test hashes on Linux
    runs-on: [self-hosted, Linux, X64, icicle]
    needs: [check-changed-files, check-format]
    strategy:
      matrix:
        hash:
          - name: keccak
            build_args:
    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'
      # builds a single hash algorithm with the hash's specified build args
      run: ./build.sh -hash=${{ matrix.hash.name }} ${{ matrix.hash.build_args }}
    - name: Test
      working-directory: ./wrappers/golang/hash
      if: needs.check-changed-files.outputs.golang == 'true' || needs.check-changed-files.outputs.cpp_cuda == 'true'
      run: |
        HASH=$(echo ${{ matrix.hash.name }} | sed -e 's/_//g')
        export CPATH=$CPATH:/usr/local/cuda/include
        go test ./$HASH/tests -count=1 -failfast -p 2 -timeout 60m -v
  
  # 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
