name: CI

on:
  push:
  pull_request:

jobs:
  test:
    name: "PHPUnit: MW ${{ matrix.mw }}, PHP ${{ matrix.php }}"
    continue-on-error: ${{ matrix.experimental }}

    strategy:
      matrix:
        include:
          - mw: 'REL1_43'
            php: '8.1'
            experimental: false
            coverage: false
            search-image: 'docker-registry.wikimedia.org/repos/search-platform/cirrussearch-elasticsearch-image:v7.10.2-12'
          - mw: 'REL1_43'
            php: '8.2'
            experimental: false
            coverage: true
            search-image: 'docker-registry.wikimedia.org/repos/search-platform/cirrussearch-elasticsearch-image:v7.10.2-12'
          - mw: 'REL1_44'
            php: '8.3'
            experimental: false
            coverage: false
            search-image: 'docker-registry.wikimedia.org/repos/search-platform/cirrussearch-elasticsearch-image:v7.10.2-12'
          - mw: 'REL1_45'
            php: '8.4'
            experimental: false
            coverage: false
            search-image: 'docker-registry.wikimedia.org/repos/search-platform/cirrussearch-elasticsearch-image:v7.10.2-12'
          - mw: 'master'
            php: '8.5'
            experimental: false
            coverage: false
            search-image: 'docker-registry.wikimedia.org/repos/search-platform/cirrussearch-opensearch-image:v1.3.20-12'

    runs-on: ubuntu-latest

    services:
      elasticsearch:
        image: ${{ matrix.search-image }}
        ports:
          - 9200:9200
          - 9300:9300
        env:
          discovery.type: single-node
          ES_JAVA_OPTS: "-Xms512m -Xmx512m -Dlog4j2.formatMsgNoLookups=true"
          OPENSEARCH_JAVA_OPTS: "-Xms512m -Xmx512m"

    defaults:
      run:
        working-directory: mediawiki

    steps:
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php }}
          extensions: mbstring, intl
          tools: composer

      - name: Cache MediaWiki
        id: cache-mediawiki
        uses: actions/cache@v4
        with:
          path: |
            mediawiki
            !mediawiki/extensions/
            !mediawiki/vendor/
          key: mw_${{ matrix.mw }}-php${{ matrix.php }}_v3

      - name: Cache Composer cache
        uses: actions/cache@v4
        with:
          path: ~/.composer/cache
          key: composer-php${{ matrix.php }}

      - uses: actions/checkout@v4
        with:
          path: EarlyCopy

      - name: Install MediaWiki
        if: steps.cache-mediawiki.outputs.cache-hit != 'true'
        working-directory: ~
        run: bash EarlyCopy/.github/workflows/installMediaWiki.sh ${{ matrix.mw }} WikibaseFacetedSearch

      - uses: actions/checkout@v4
        with:
          path: mediawiki/extensions/WikibaseFacetedSearch

      - run: composer update

      - name: Run update.php
        run: php maintenance/update.php --quick

      - name: Create ElasticSearch index
        run: php extensions/CirrusSearch/maintenance/UpdateSearchIndexConfig.php

      - name: Index pages
        run: |
          php extensions/CirrusSearch/maintenance/ForceSearchIndex.php --skipParse
          php extensions/CirrusSearch/maintenance/ForceSearchIndex.php --skipLinks --indexOnSkip
          php maintenance/runJobs.php

      - name: Run PHPUnit
        run: |
          if [ -f tests/phpunit/phpunit.php ]; then
            php tests/phpunit/phpunit.php -c extensions/WikibaseFacetedSearch/
          else
            composer phpunit -- extensions/WikibaseFacetedSearch/tests/
          fi
        if: ${{ ! matrix.coverage }}

      - name: Run PHPUnit with code coverage
        run: |
          if [ -f tests/phpunit/phpunit.php ]; then
            php tests/phpunit/phpunit.php -c extensions/WikibaseFacetedSearch/ --coverage-clover coverage.xml
          else
            composer phpunit -- extensions/WikibaseFacetedSearch/tests/ --coverage-clover coverage.xml
          fi
        if: ${{ matrix.coverage }}

      - name: Upload code coverage
        uses: codecov/codecov-action@v5
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
        if: ${{ matrix.coverage }}

  PHPStan:
    name: "PHPStan: MW ${{ matrix.mw }}, PHP ${{ matrix.php }}"

    strategy:
      matrix:
        include:
          - mw: 'REL1_43'
            php: '8.3'

    runs-on: ubuntu-latest

    defaults:
      run:
        working-directory: mediawiki

    steps:
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php }}
          extensions: mbstring
          tools: composer, cs2pr

      - name: Cache MediaWiki
        id: cache-mediawiki
        uses: actions/cache@v4
        with:
          path: |
            mediawiki
            mediawiki/extensions/
            mediawiki/vendor/
          key: mw_${{ matrix.mw }}-php${{ matrix.php }}_v3

      - name: Cache Composer cache
        uses: actions/cache@v4
        with:
          path: ~/.composer/cache
          key: composer_static_analysis

      - uses: actions/checkout@v4
        with:
          path: EarlyCopy

      - name: Install MediaWiki
        if: steps.cache-mediawiki.outputs.cache-hit != 'true'
        working-directory: ~
        run: bash EarlyCopy/.github/workflows/installMediaWiki.sh ${{ matrix.mw }} WikibaseFacetedSearch

      - uses: actions/checkout@v4
        with:
          path: mediawiki/extensions/WikibaseFacetedSearch

      - name: Composer allow-plugins
        run: composer config --no-plugins allow-plugins.composer/installers true

      - run: composer update

      - name: Composer install
        run: cd extensions/WikibaseFacetedSearch && composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader

      - name: PHPStan
        run: cd extensions/WikibaseFacetedSearch && php vendor/bin/phpstan analyse --error-format=checkstyle --no-progress | cs2pr

  phpcs:
    name: "Code style: MW ${{ matrix.mw }}, PHP ${{ matrix.php }}"

    strategy:
      matrix:
        include:
          - mw: 'REL1_43'
            php: '8.2'

    runs-on: ubuntu-latest

    defaults:
      run:
        working-directory: mediawiki/extensions/WikibaseFacetedSearch

    steps:
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php }}
          extensions: mbstring, intl, php-ast
          tools: composer

      - name: Cache MediaWiki
        id: cache-mediawiki
        uses: actions/cache@v4
        with:
          path: |
            mediawiki
            !mediawiki/extensions/
            !mediawiki/vendor/
          key: mw_static_analysis

      - name: Cache Composer cache
        uses: actions/cache@v4
        with:
          path: ~/.composer/cache
          key: mw_${{ matrix.mw }}-php${{ matrix.php }}_v3

      - name: Install MediaWiki
        if: steps.cache-mediawiki.outputs.cache-hit != 'true'
        working-directory: ~
        run: curl EarlyCopy/.github/workflows/installMediaWiki.sh | bash -s ${{ matrix.mw }} WikibaseFacetedSearch

      - uses: actions/checkout@v4
        with:
          path: mediawiki/extensions/WikibaseFacetedSearch

      - name: Composer install
        run: composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader

      - run: vendor/bin/phpcs -p -s

  npm-lint:
    name: "NPM: Lint"

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22

      - name: Setup NPM dependencies
        run: npm ci

      - name: Lint i18n
        run: npm run lint:i18n

      - name: Lint styles
        run: npm run lint:styles

      - name: Lint JS
        run: npm run lint:js
  
  npm-test:
    name: "NPM: Unit test"

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22

      - name: Setup NPM dependencies
        run: npm ci

      - name: Run Jest with code coverage
        run: npm run test:unit
