name: Tests

on:
  pull_request:
    branches: [ "main" ]
    types: [ opened, synchronize, reopened ]
    paths:
      - 'src/**'
      - 'config/**'
      - '.github/workflows/tests.yml'
      - 'bin/**'
      - 'composer.json'
      - 'box.json'
      - '.php-cs-fixer.php'

permissions: read-all

env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

jobs:
  php-cs-fixer:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: "Checkout"
        uses: actions/checkout@v4

      - name: "Setup PHP"
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.4'
          extensions: curl, openssl, mbstring
          ini-values: memory_limit=-1
          tools: pecl, composer, php-cs-fixer

      - name: Run PHP-CS-Fixer fix
        run: php-cs-fixer fix --dry-run --diff --ansi

  phpstan:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: "Checkout"
        uses: actions/checkout@v4

      - name: "Setup PHP"
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.4'
          extensions: curl, openssl, mbstring
          ini-values: memory_limit=-1
          tools: composer
        env:
          phpts: zts

      - name: "Cache Composer packages"
        id: composer-cache
        uses: actions/cache@v4
        with:
          path: vendor
          key: ${{ runner.os }}-phpstan-${{ hashFiles('**/composer.lock') }}
          restore-keys: |
            ${{ runner.os }}-phpstan-

      - name: "Install Dependencies"
        run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist

      - name: "Run phpstan"
        run: vendor/bin/phpstan analyse

  phpunit:
    name: "PHPUnit (PHP ${{ matrix.php }})"
    runs-on: ubuntu-latest
    timeout-minutes: 10
    strategy:
      matrix:
        include:
          - php: '8.4'

    steps:
      - name: "Checkout"
        uses: actions/checkout@v4

      - name: "Setup PHP"
        uses: shivammathur/setup-php@v2
        with:
          php-version: "${{ matrix.php }}"
          tools: pecl, composer
          extensions: curl, openssl, mbstring
          ini-values: memory_limit=-1

      - name: "Cache Composer packages"
        id: composer-cache
        uses: actions/cache@v4
        with:
          path: vendor
          key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
          restore-keys: |
            ${{ runner.os }}-php

      - name: "Install Dependencies"
        run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist

      - name: "Run PHPUnit Tests"
        run: SPC_LIBC=glibc vendor/bin/phpunit tests/ --no-coverage

  define-matrix:
    name: "Define Matrix"
    runs-on: ubuntu-latest
    outputs:
      php: ${{ steps.gendef.outputs.php }}
      os: ${{ steps.gendef.outputs.os }}
    steps:
      - name: "Checkout"
        uses: actions/checkout@v4

      - name: "Setup PHP"
        uses: shivammathur/setup-php@v2
        with:
          php-version: 8.4
          extensions: curl, openssl, mbstring

      - name: Define
        id: gendef
        run: |
          PHP_VERSIONS=$(php src/globals/test-extensions.php php)
          OS_VERSIONS=$(php src/globals/test-extensions.php os)
          echo 'php='"$PHP_VERSIONS" >> "$GITHUB_OUTPUT"
          echo 'os='"$OS_VERSIONS" >> "$GITHUB_OUTPUT"


  build:
    name: "Build PHP Test (PHP ${{ matrix.php }} ${{ matrix.os }})"
    runs-on: ${{ matrix.os }}
    needs: [define-matrix, php-cs-fixer, phpstan, phpunit]
    timeout-minutes: 120
    strategy:
      matrix:
        php: ${{ fromJSON(needs.define-matrix.outputs.php) }}
        os: ${{ fromJSON(needs.define-matrix.outputs.os) }}
      fail-fast: false
    steps:
      - name: "Update runner packages"
        if: ${{ startsWith(matrix.os, 'ubuntu-') }}
        run: sudo apt-get update && sudo apt-get install -y ca-certificates

      - name: "Checkout"
        uses: actions/checkout@v4

      - name: "Setup PHP"
        uses: shivammathur/setup-php@v2
        with:
          php-version: 8.4
          tools: pecl, composer
          extensions: curl, openssl, mbstring
          ini-values: memory_limit=-1
        env:
          phpts: nts

      - name: "Cache composer packages"
        id: composer-cache
        uses: actions/cache@v4
        with:
          path: vendor
          key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
          restore-keys: |
            ${{ runner.os }}-php-

      # Cache downloaded source
      - id: cache-download
        uses: actions/cache@v4
        with:
          path: downloads
          key: php-dependencies-${{ matrix.os }}

      - name: "Install Dependencies"
        run: composer update -vvv --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --no-plugins

      - name: "Run Build Tests (doctor)"
        run: php src/globals/test-extensions.php doctor_cmd ${{ matrix.os }} ${{ matrix.php }}

      - name: "Prepare UPX for Windows"
        if: ${{ startsWith(matrix.os, 'windows-') }}
        run: |
          php src/globals/test-extensions.php install_upx_cmd ${{ matrix.os }} ${{ matrix.php }}
          echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $env:GITHUB_ENV

      - name: "Prepare UPX for Linux"
        if: ${{ startsWith(matrix.os, 'ubuntu-') }}
        run: |
          php src/globals/test-extensions.php install_upx_cmd ${{ matrix.os }} ${{ matrix.php }}
          echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $GITHUB_ENV

      - name: "Run Build Tests (download)"
        run: php src/globals/test-extensions.php download_cmd ${{ matrix.os }} ${{ matrix.php }}

      - name: "Run Build Tests (build)"
        run: php src/globals/test-extensions.php build_cmd ${{ matrix.os }} ${{ matrix.php }}

      - name: "Run Build Tests (build - embed for non-windows)"
        if: ${{ !startsWith(matrix.os, 'windows-') }}
        run: php src/globals/test-extensions.php build_embed_cmd ${{ matrix.os }} ${{ matrix.php }}

      - name: "Upload logs"
        if: ${{ always() && hashFiles('log/**') != '' }}
        uses: actions/upload-artifact@v4
        with:
          name: build-logs-${{ matrix.os }}-${{ matrix.php }}
          path: log

#      - name: Setup tmate session
#        if: ${{ failure() }}
#        uses: mxschmitt/action-tmate@v3
