on:
  push:
    branches:
      - master
    paths-ignore:
      - "**.md"
      - "!.github/workflows/*.yml"
      - "!rln-wasm/**"
      - "!rln/src/**"
      - "!rln/resources/**"
      - "!utils/src/**"
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
    paths-ignore:
      - "**.md"
      - "!.github/workflows/*.yml"
      - "!rln-wasm/**"
      - "!rln/src/**"
      - "!rln/resources/**"
      - "!utils/src/**"

name: CI

jobs:
  utils-test:
    # skip tests on draft PRs
    if: github.event_name == 'push' || (github.event_name == 'pull_request' && !github.event.pull_request.draft)
    strategy:
      matrix:
        platform: [ubuntu-latest, macos-latest]
        crate: [utils]
    runs-on: ${{ matrix.platform }}
    timeout-minutes: 60

    name: Test - ${{ matrix.crate }} - ${{ matrix.platform }}
    steps:
      - name: Checkout sources
        uses: actions/checkout@v4
      - name: Install stable toolchain
        uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - name: Install dependencies
        run: make installdeps
      - name: Test utils
        run: |
          cargo make test --release
        working-directory: ${{ matrix.crate }}

  rln-test:
    # skip tests on draft PRs
    if: github.event_name == 'push' || (github.event_name == 'pull_request' && !github.event.pull_request.draft)
    strategy:
      matrix:
        platform: [ubuntu-latest, macos-latest]
        crate: [rln]
        feature: ["default", "stateless"]
    runs-on: ${{ matrix.platform }}
    timeout-minutes: 60

    name: Test - ${{ matrix.crate }} - ${{ matrix.platform }} - ${{ matrix.feature }}
    steps:
      - name: Checkout sources
        uses: actions/checkout@v4
      - name: Install stable toolchain
        uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - name: Install dependencies
        run: make installdeps
      - name: Test rln
        run: |
          if [ ${{ matrix.feature }} == default ]; then
            cargo make test --release
          else
            cargo make test_${{ matrix.feature }} --release
          fi
        working-directory: ${{ matrix.crate }}

  rln-wasm-test:
    # skip tests on draft PRs
    if: github.event_name == 'push' || (github.event_name == 'pull_request' && !github.event.pull_request.draft)
    strategy:
      matrix:
        platform: [ubuntu-latest, macos-latest]
        crate: [rln-wasm]
        feature: ["default"]
    runs-on: ${{ matrix.platform }}
    timeout-minutes: 60

    name: Test - ${{ matrix.crate }} - ${{ matrix.platform }} - ${{ matrix.feature }}
    steps:
      - uses: actions/checkout@v4
      - name: Install stable toolchain
        uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - name: Install dependencies
        run: make installdeps
      - name: Build rln-wasm
        run: cargo make build
        working-directory: ${{ matrix.crate }}
      - name: Test rln-wasm on node
        run: cargo make test --release
        working-directory: ${{ matrix.crate }}
      - name: Test rln-wasm on browser
        run: cargo make test_browser --release
        working-directory: ${{ matrix.crate }}

  rln-wasm-parallel-test:
    # skip tests on draft PRs
    if: github.event_name == 'push' || (github.event_name == 'pull_request' && !github.event.pull_request.draft)
    strategy:
      matrix:
        platform: [ubuntu-latest, macos-latest]
        crate: [rln-wasm]
        feature: ["parallel"]
    runs-on: ${{ matrix.platform }}
    timeout-minutes: 60

    name: Test - ${{ matrix.crate }} - ${{ matrix.platform }} - ${{ matrix.feature }}
    steps:
      - uses: actions/checkout@v4
      - name: Install nightly toolchain
        uses: dtolnay/rust-toolchain@nightly
        with:
          components: rust-src
          targets: wasm32-unknown-unknown
      - uses: Swatinem/rust-cache@v2
      - name: Install dependencies
        run: make installdeps
      - name: Build rln-wasm in parallel mode
        run: cargo make build_parallel
        working-directory: ${{ matrix.crate }}
      - name: Test rln-wasm in parallel mode on browser
        run: cargo make test_parallel --release
        working-directory: ${{ matrix.crate }}

  lint:
    # run on both ready and draft PRs
    if: github.event_name == 'push' || (github.event_name == 'pull_request' && !github.event.pull_request.draft)
    strategy:
      matrix:
        # run lint tests only on ubuntu
        platform: [ubuntu-latest]
        crate: [rln, rln-wasm, utils]
    runs-on: ${{ matrix.platform }}
    timeout-minutes: 60

    name: Lint - ${{ matrix.crate }} - ${{ matrix.platform }}
    steps:
      - name: Checkout sources
        uses: actions/checkout@v4
      - name: Install stable toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy
      - name: Install wasm32 target
        if: matrix.crate == 'rln-wasm'
        run: rustup target add wasm32-unknown-unknown
      - uses: Swatinem/rust-cache@v2
      - name: Install dependencies
        run: make installdeps
      - name: Check formatting
        if: success() || failure()
        run: cargo fmt -- --check
        working-directory: ${{ matrix.crate }}
      - name: Check clippy wasm target
        if: (success() || failure()) && (matrix.crate == 'rln-wasm')
        run: |
          cargo clippy --target wasm32-unknown-unknown --tests --release -- -D warnings
        working-directory: ${{ matrix.crate }}
      - name: Check clippy default feature
        if: (success() || failure()) && (matrix.crate != 'rln-wasm')
        run: |
          cargo clippy --all-targets --tests --release -- -D warnings
      - name: Check clippy stateless feature
        if: (success() || failure()) && (matrix.crate == 'rln')
        run: |
          cargo clippy --all-targets --tests --release --features=stateless --no-default-features -- -D warnings
        working-directory: ${{ matrix.crate }}

  benchmark-utils:
    # run only on ready PRs
    if: github.event_name == 'pull_request' && !github.event.pull_request.draft
    strategy:
      matrix:
        # run benchmark tests only on ubuntu
        platform: [ubuntu-latest]
        crate: [utils]
    runs-on: ${{ matrix.platform }}
    timeout-minutes: 60

    name: Benchmark - ${{ matrix.crate }} - ${{ matrix.platform }}
    steps:
      - name: Checkout sources
        uses: actions/checkout@v4
      - uses: Swatinem/rust-cache@v2
      - uses: boa-dev/criterion-compare-action@v3
        with:
          branchName: ${{ github.base_ref }}
          cwd: ${{ matrix.crate }}

  benchmark-rln:
    # run only on ready PRs
    if: github.event_name == 'pull_request' && !github.event.pull_request.draft
    strategy:
      matrix:
        # run benchmark tests only on ubuntu
        platform: [ubuntu-latest]
        crate: [rln]
        feature: ["default"]
    runs-on: ${{ matrix.platform }}
    timeout-minutes: 60

    name: Benchmark - ${{ matrix.crate }} - ${{ matrix.platform }} - ${{ matrix.feature }}
    steps:
      - name: Checkout sources
        uses: actions/checkout@v4
      - uses: Swatinem/rust-cache@v2
      - uses: boa-dev/criterion-compare-action@v3
        with:
          branchName: ${{ github.base_ref }}
          cwd: ${{ matrix.crate }}
          features: ${{ matrix.feature }}
