name: Run unit tests

on: [push, pull_request]
permissions:
  contents: read

jobs:
  lint:
    name: Check PHP syntax
    runs-on: ubuntu-latest
    steps:
      - name: Set up PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '7.4'
          tools: composer:v2
          coverage: none
        env:
          fail-fast: true

      - uses: actions/checkout@v4

      - name: Get Composer Cache Directories
        id: composer-cache
        run: |
          echo "files_cache=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
          echo "vcs_cache=$(composer config cache-vcs-dir)" >> $GITHUB_OUTPUT

      - name: Generate composer.lock
        run: |
          composer update --no-install
        env:
          COMPOSER_ROOT_VERSION: dev-master

      - name: Cache composer cache
        uses: actions/cache@v4
        with:
          path: |
            ${{ steps.composer-cache.outputs.files_cache }}
            ${{ steps.composer-cache.outputs.vcs_cache }}
          key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
          restore-keys: |
            ${{ runner.os }}-composer-

      - name: Run composer install
        run: composer install -o
        env:
          COMPOSER_ROOT_VERSION: dev-master

      - run: |
          git ls-files | grep \\\.php$ | grep -v ^dictionaries/scripts/* | ./vendor/bin/parallel-lint --stdin

  code-style:
    name: Code Style Analysis
    runs-on: ubuntu-latest
    steps:
      - name: Set up PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '7.4'
          tools: composer:v2
          coverage: none
        env:
          fail-fast: true

      - uses: actions/checkout@v4

      - name: Get Composer Cache Directories
        id: composer-cache
        run: |
          echo "files_cache=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
          echo "vcs_cache=$(composer config cache-vcs-dir)" >> $GITHUB_OUTPUT

      - name: Generate composer.lock
        run: composer update --no-install
        env:
          COMPOSER_ROOT_VERSION: dev-master

      - name: Cache composer cache
        uses: actions/cache@v4
        with:
          path: |
            ${{ steps.composer-cache.outputs.files_cache }}
            ${{ steps.composer-cache.outputs.vcs_cache }}
          key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
          restore-keys: |
            ${{ runner.os }}-composer-

      - name: Run composer install
        run: composer install -o
        env:
          COMPOSER_ROOT_VERSION: dev-master

      - name: Code Style Analysis with PHPCS
        run: vendor/bin/phpcs -d memory_limit=512M

  chunk-matrix:
    permissions:
      contents: none
    name: Generate Chunk Matrix

    runs-on: ubuntu-latest
    env:
      CHUNK_COUNT: 8

    outputs:
      count: ${{ steps.chunk-matrix.outputs.count }}
      chunks: ${{ steps.chunk-matrix.outputs.chunks }}

    steps:
      - id: chunk-matrix
        name: Generates the Chunk Matrix
        run: |
          echo "count=$(php -r 'echo json_encode([ ${{ env.CHUNK_COUNT }} ]);')" >> $GITHUB_OUTPUT
          echo "chunks=$(php -r 'echo json_encode(range(1, ${{ env.CHUNK_COUNT }} ));')" >> $GITHUB_OUTPUT

  tests:
    name: "Unit Tests - PHP ${{ matrix.php-version }} ${{ matrix.chunk }}/${{ matrix.count }}"

    runs-on: ubuntu-latest
    needs:
      - chunk-matrix

    strategy:
      fail-fast: false
      matrix:
        php-version:
          - "8.0"
          - "8.1"
          - "8.2"
          - "8.3"
        count: ${{ fromJson(needs.chunk-matrix.outputs.count) }}
        chunk: ${{ fromJson(needs.chunk-matrix.outputs.chunks) }}

    env:
      CHUNK_COUNT: "${{ matrix.count }}"
      CHUNK_NUMBER: "${{ matrix.chunk }}"
      PARALLEL_PROCESSES: 5
      BRANCH_NAME: ${{ github.head_ref || github.ref_name }}

    steps:
      - name: Set up PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: "${{ matrix.php-version }}"
          ini-values: zend.assertions=1, assert.exception=1, opcache.enable_cli=1, opcache.jit=function, opcache.jit_buffer_size=512M
          tools: composer:v2
          coverage: none
          extensions: none, curl, dom, filter, intl, json, libxml, mbstring, opcache, openssl, pcre, phar, reflection, simplexml, spl, tokenizer, xml, xmlwriter
        env:
          fail-fast: true

      - uses: actions/checkout@v4

      - name: Get Composer Cache Directories
        id: composer-cache
        run: |
          echo "files_cache=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
          echo "vcs_cache=$(composer config cache-vcs-dir)" >> $GITHUB_OUTPUT

      - name: Generate composer.lock
        run: |
          composer update --no-install
        env:
          COMPOSER_ROOT_VERSION: dev-master

      - name: Cache composer cache
        uses: actions/cache@v4
        with:
          path: |
            ${{ steps.composer-cache.outputs.files_cache }}
            ${{ steps.composer-cache.outputs.vcs_cache }}
          key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
          restore-keys: |
            ${{ runner.os }}-composer-

      - name: Run composer install
        run: composer install -o
        env:
          COMPOSER_ROOT_VERSION: dev-master

      - name: Run unit tests
        run: bin/tests-github-actions.sh
