name: CI
on:
  pull_request:
  push:
    branches:
      - master

env:
  RUST_BACKTRACE: 1

jobs:
  ci-pass:
    name: CI is green
    runs-on: ubuntu-latest
    needs:
      - test
      - simd
      - check_x86
      - msrv_x64
      - msrv_aarch64
      - miri
      - clippy_check
    steps:
      - run: exit 0

  test:
    name: Test ${{ matrix.rust }} on ${{ matrix.os }}
    strategy:
      matrix:
        rust:
          - stable
          - beta
          - nightly

        os:
          - ubuntu-latest
          - windows-latest
          - macOS-latest

        include:
          - rust: nightly
            benches: true

    runs-on: ${{ matrix.os }}
    env:
      CARGO_CFG_HTTPARSE_DISABLE_SIMD: 1

    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Install Rust (${{ matrix.rust }})
        uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: ${{ matrix.rust }}
          override: true

      - name: no_std
        uses: actions-rs/cargo@v1
        with:
          command: build
          args: --no-default-features

      - name: Test
        uses: actions-rs/cargo@v1
        with:
          command: test

      - name: Test all benches
        if: matrix.benches
        uses: actions-rs/cargo@v1
        with:
          command: test
          args: --benches

  simd:
    name: SIMD ${{ matrix.target_feature }} on ${{ matrix.rust }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        rust:
          - stable
          - beta
          - nightly

        target_feature:
          - "+sse4.2"
          - "+avx2"
          - "+sse4.2,+avx2"

        disable_compiletime:
          - 0
          - 1

    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Install Rust (${{ matrix.rust }})
        uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: ${{ matrix.rust }}
          override: true

      - name: Test
        uses: actions-rs/cargo@v1
        with:
          command: test
        env:
          RUSTFLAGS: -C target_feature=${{ matrix.target_feature }}
          CARGO_CFG_HTTPARSE_DISABLE_SIMD_COMPILETIME: ${{ matrix.disable_compiletime }}

  check_x86:
    name: check x86
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Setup Rust
        uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: stable
          override: true
          target: i686-unknown-linux-musl

      - name: Test without SIMD
        uses: actions-rs/cargo@v1
        with:
          command: test
          args: --target i686-unknown-linux-musl
        env:
          CARGO_CFG_HTTPARSE_DISABLE_SIMD_COMPILETIME: 1

      - name: Test

        uses: actions-rs/cargo@v1
        with:
          command: test
          args: --target i686-unknown-linux-musl

  msrv_x64:
    name: msrv (x64)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Install Rust
        uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: 1.36.0
          override: true

      # Only build, dev-dependencies don't compile on 1.36.0
      - name: Build
        uses: actions-rs/cargo@v1
        with:
          command: build

  # This tests that aarch64 gracefully fallbacks to SWAR if neon_intrinsics aren't available (<1.59)
  msrv_aarch64:
    name: msrv (aarch64)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Install cross-compiling dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y gcc-aarch64-linux-gnu

      - name: Setup Rust
        uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: 1.36.0
          override: true
          target: aarch64-unknown-linux-gnu

      # Only build, dev-dependencies don't compile on 1.36.0
      - name: Build
        uses: actions-rs/cargo@v1
        with:
          command: build
          args: --target aarch64-unknown-linux-gnu

  clippy_check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run clippy
        run: cargo clippy --all-targets --all-features

  miri:
    name: Test with Miri
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Install Rust
        uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: nightly
          components: miri
          override: true

      - name: Test
        run: cargo miri test
  #
  # mirai:
  #   name: MIRAI static analysis
  #   runs-on: ubuntu-latest
  #
  #   steps:
  #     - name: Checkout
  #       uses: actions/checkout@v1
  #
  #     - name: Install Rust
  #       uses: actions-rs/toolchain@v1
  #       with:
  #         profile: minimal
  #         toolchain: nightly-2023-05-09
  #         components: clippy, rustfmt, rustc-dev, rust-src, rust-std, llvm-tools-preview
  #         override: true
  #
  #     - name: install mirai
  #       run: cargo install --locked --git https://github.com/facebookexperimental/MIRAI/ mirai
  #       env:
  #         # MIRAI_FLAGS: --diag=(default|verify|library|paranoid)
  #         MIRAI_FLAGS: --diag=default
  #
  #     - name: cargo mirai
  #       run: cargo mirai --lib

  aarch64:
    name: Test aarch64 (neon)
    runs-on: ubuntu-latest
    env:
      CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2

      - name: Setup Rust
        uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: stable
          override: true
          target: aarch64-unknown-linux-gnu

      - name: Install QEMU and dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y qemu qemu-user gcc-aarch64-linux-gnu

      - name: Build tests
        run: cargo build --tests --target aarch64-unknown-linux-gnu

      - name: Run tests with QEMU
        run: |
          test_binaries=$(find target/aarch64-unknown-linux-gnu/debug/deps/ -type f -executable -name 'httparse-*')
          if [ -n "$test_binaries" ]; then
            for test_binary in $test_binaries
            do
              echo "Running tests in ${test_binary}"
              /usr/bin/qemu-aarch64 -L /usr/aarch64-linux-gnu/ "${test_binary}"
            done
          else
            echo "No test binaries found."
          fi
