---
# This is a basic workflow to check code with PHPSTAN tool
name: PHPStan

# Controls when the workflow will run
on:
  # workflow called by the parent workflow ci.yml
  workflow_call:
    inputs:
      gh_event:
        required: true
        type: string
  # can run job manually
  workflow_dispatch:

concurrency:
  group: phpstan-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

env:
  gh_event: ${{ inputs.gh_event || github.event_name }}
  CACHE_KEY_PART: ${{ ( inputs.gh_event == 'pull_request' || github.event_name == 'pull_request' ) && format('{0}-{1}', github.base_ref, github.head_ref) || github.ref_name }}
  GITHUB_JSON: ${{ toJSON(github) }}  # Helps in debugging Github Action
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job
  php-stan:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        php-version:
          # PHPStan requires PHP >= 7.2.
          #- "7.2"
          - '8.2'
    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v6
      # Get PHP and addons
      - name: Setup PHP
        id: setup-php
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php-version }}
          coverage: none # disable xdebug, pcov
          tools: phpstan:2.1.12, cs2pr:1.8.6
          extensions: calendar, json, imagick, gd, zip, mbstring, intl, opcache, imap,
            mysql, pgsql, sqlite3, ldap, xml, mcrypt

      # Restore old cache
      - name: Restore phpstan cache
        id: cache
        uses: actions/cache/restore@v5
        with:
          path: ./.github/tmp
          key: phpstan-cache-${{ matrix.php-version }}-${{ env.CACHE_KEY_PART }}-${{
            github.run_id }}
          restore-keys: |
            phpstan-cache-${{ matrix.php-version }}-${{ env.CACHE_KEY_PART }}-
            phpstan-cache-${{ matrix.php-version }}-${{ github.head_ref }}-
            phpstan-cache-${{ matrix.php-version }}-${{ github.base_ref }}-
            phpstan-cache-${{ matrix.php-version }}-

      - name: Show debug into
        run: cd ./.github/tmp && ls -al

      # Another method to get the list of changed files
      # It sets the variable steps.changed-php.outputs.all_changed_files for other steps
      - name: Get all changed php files (if PR)
        id: changed-php
        if: env.gh_event == 'pull_request'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: ./.github/scripts/get_changed_php.sh

      #- name: Get changed PHP files
      #  id: files
      #  run: |
      #    git fetch origin ${{ github.base_ref }}
      #    FILES=$(git diff --name-only "origin/${{ github.base_ref }}...HEAD" | grep '\.php$' || true)
      #    {
      #      echo "files<<EOF"
      #      echo "$FILES"
      #      echo "EOF"
      #    } > "$GITHUB_OUTPUT"

      # Run PHPStan
      - name: Run PHPStan
        id: phpstan
        # Proceed when:
        #   - the action is not cancelled
        #  AND
        #   - the branch is an integration branch (no merge), or,
        #   - the merge from branch contains 'phpstan_full', or,
        #   - there are changes in PHP files.
        if: ${{ ! cancelled() && (github.ref_name == 'develop' || github.ref_name == 'refs/heads/develop' || endsWith(github.ref_name, '.0') || contains(github.head_ref, 'phpstan_full') || steps.changed-php.outputs.any_changed == 'true') }}
        env:
          ALL_CHANGED_FILES: ${{ steps.changed-php.outputs.all_changed_files }}
        # shellcheck disable=2086
        run: |
          # shellcheck disable=2086
          > /tmp/phpstan-files.txt
          if [ "${{ github.ref_name }}" == "develop" ] || [[ "${{ github.ref_name }}" == *.0 ]]|| [[ "${{ github.head_ref }}" == *"phpstan_full"* ]] ; then
            # Run on all files in integration branch
            phpstan -vvv analyse --error-format=checkstyle --memory-limit 7G -a dev/build/phpstan/bootstrap_action.php | tee _stan.xml | cs2pr --graceful-warnings

          else
            echo "$ALL_CHANGED_FILES" >> /tmp/phpstan-files.txt
            cat /tmp/phpstan-files.txt
            phpstan -vvv analyse --error-format=checkstyle --memory-limit 7G -a dev/build/phpstan/bootstrap_action.php ${ALL_CHANGED_FILES} | tee _stan.xml | cs2pr --graceful-warnings
          fi
        # continue-on-error: true

      # Save cache
      - name: Save phpstan cache
        uses: actions/cache/save@v5
        if: ${{ success() || ( ! cancelled() && steps.cache.outputs.cache-hit != 'true' ) }}
        with:
          path: ./.github/tmp
          key: phpstan-cache-${{ matrix.php-version }}-${{ env.CACHE_KEY_PART }}-${{
            github.run_id }}
      - name: Provide phpstan log as artifact
        uses: actions/upload-artifact@v7
        if: ${{ always() }}
        with:
          name: phpstan-srcrt
          path: ${{ github.workspace }}/_stan.xml
          retention-days: 2

      # Run PHPStan generate baseline
      # - name: Run PHPStan generate baseline
      #   id: phpstan-baseline
      #   if: ${{ success() }}
      #   run: |
      #     phpstan -vv analyse --memory-limit 7G -a dev/build/phpstan/bootstrap_action.php --generate-baseline dev/build/phpstan/phpstan-baseline.neon
