name: Matrix Test
on:
  push:
    branches: [main, devel]
  pull_request:
    branches: [main, devel]

jobs:
  run-if-changes:
    runs-on: ubuntu-latest
    outputs:
      run: ${{ (github.event_name == 'push' && github.ref_name == 'main') && 'true' || steps.filter.outputs.python }}
    steps:
      - uses: actions/checkout@v6
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            python:
              - 'ultraplot/**'

  get-versions:
    runs-on: ubuntu-latest
    needs:
      - run-if-changes
    if: always() && needs.run-if-changes.outputs.run == 'true'
    outputs:
      python-versions: ${{ steps.set-versions.outputs.python-versions }}
      matplotlib-versions: ${{ steps.set-versions.outputs.matplotlib-versions }}
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - uses: actions/setup-python@v6
        with:
          python-version: "3.11"

      - name: Install dependencies
        run: pip install tomli

      - id: set-versions
        run: |
          # Create a Python script to read and parse versions
          cat > get_versions.py << 'EOF'
          import tomli
          import re
          import json

          # Read pyproject.toml
          with open("pyproject.toml", "rb") as f:
              data = tomli.load(f)

          # Get Python version requirement
          python_req = data["project"]["requires-python"]

          # Parse min and max versions
          min_version = re.search(r">=(\d+\.\d+)", python_req)
          max_version = re.search(r"<(\d+\.\d+)", python_req)

          python_versions = []
          if min_version and max_version:
              # Convert version strings to tuples
              min_v = tuple(map(int, min_version.group(1).split(".")))
              max_v = tuple(map(int, max_version.group(1).split(".")))

              # Generate version list
              current = min_v
              while current < max_v:
                  python_versions.append(".".join(map(str, current)))
                  current = (current[0], current[1] + 1)


          # parse MPL versions
          mpl_req = None
          for d in data["project"]["dependencies"]:
            if d.startswith("matplotlib"):
              mpl_req = d
              break
          assert mpl_req is not None, "matplotlib version not found in dependencies"
          min_version = re.search(r">=(\d+\.\d+)", mpl_req)
          max_version = re.search(r"<(\d+\.\d+)", mpl_req)

          mpl_versions = []
          if min_version and max_version:
              # Convert version strings to tuples
              min_v = tuple(map(int, min_version.group(1).split(".")))
              max_v = tuple(map(int, max_version.group(1).split(".")))

              # Generate version list
              current = min_v
              while current < max_v:
                  mpl_versions.append(".".join(map(str, current)))
                  current = (current[0], current[1] + 1)

          # If no versions found, default to 3.9
          if not mpl_versions:
              mpl_versions = ["3.9"]

          # Create output dictionary
          output = {
              "python_versions": python_versions,
              "matplotlib_versions": mpl_versions
          }

          # Print as JSON
          print(json.dumps(output))
          EOF

          # Run the script and capture output
          OUTPUT=$(python3 get_versions.py)
          PYTHON_VERSIONS=$(echo $OUTPUT | jq -r '.python_versions')
          MPL_VERSIONS=$(echo $OUTPUT | jq -r '.matplotlib_versions')

          echo "Detected Python versions: ${PYTHON_VERSIONS}"
          echo "Detected Matplotlib versions: ${MPL_VERSIONS}"
          echo "python-versions=$(echo $PYTHON_VERSIONS | jq -c)" >> $GITHUB_OUTPUT
          echo "matplotlib-versions=$(echo $MPL_VERSIONS | jq -c)" >> $GITHUB_OUTPUT

  build:
    needs:
      - get-versions
      - run-if-changes
    if: always() && needs.run-if-changes.outputs.run == 'true' && needs.get-versions.result == 'success'
    strategy:
      matrix:
        python-version: ${{ fromJson(needs.get-versions.outputs.python-versions) }}
        matplotlib-version: ${{ fromJson(needs.get-versions.outputs.matplotlib-versions) }}
      fail-fast: false
    uses: ./.github/workflows/build-ultraplot.yml
    concurrency:
      group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.python-version }}-${{ matrix.matplotlib-version }}
      cancel-in-progress: true
    with:
      python-version: ${{ matrix.python-version }}
      matplotlib-version: ${{ matrix.matplotlib-version }}

  build-success:
    needs:
      - build
      - run-if-changes
    if: always()
    runs-on: ubuntu-latest
    steps:
      - run: |
          if [[ '${{ needs.run-if-changes.outputs.run }}' == 'false' ]]; then
            echo "No changes detected, tests skipped."
          else
            if [[ '${{ needs.build.result }}' == 'success' ]]; then
              echo "All tests passed successfully!"
            else
              echo "Tests failed!"
              exit 1
            fi
          fi
