name: Tests + Code Analysis

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
  workflow_dispatch:

jobs:
  analyze:
    name: Analyze Code
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

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

    - name: Initialize CodeQL
      uses: github/codeql-action/init@v3
      with:
        languages: python

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v3

  validate-pyproject:
    name: Validate pyproject.toml
    runs-on: ubuntu-latest

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

    - name: Setup Python
      uses: actions/setup-python@v5

    - name: Install validate-pyproject
      run: pip install validate-pyproject

    - name: Validate pyproject.toml
      run: validate-pyproject pyproject.toml

  tests-linux:
    name: Unit Tests (Linux)
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request'

    strategy:
      matrix:
        python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']

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

    - name: Setup Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}

    - name: Fonts Cache
      id: cache-fonts-linux
      uses: pat-s/always-upload-cache@v2.1.5
      with:
        path: ~/.fonts/opentype
        key: fonts-linux

    - name: Download Fonts
      if: steps.cache-fonts-linux.outputs.cache-hit != 'true'
      run: |
        echo "Downloading xml2rfc-fonts"
        mkdir -p ~/.fonts/opentype ~/fonts
        wget -q -O fonts.tar.gz https://github.com/ietf-tools/xml2rfc-fonts/archive/refs/tags/3.22.0.tar.gz
        tar zxf fonts.tar.gz -C ~/fonts
        mv ~/fonts/*/noto/* ~/.fonts/opentype/
        mv ~/fonts/*/roboto_mono/* ~/.fonts/opentype/
        mkdir -p /usr/share/fonts/truetype
        ln -sf ~/.fonts/opentype/*.[to]tf /usr/share/fonts/truetype/
        echo "Reloading Font Cache..."
        fc-cache -f -v

    - name: Link Fonts
      if: steps.cache-fonts-linux.outputs.cache-hit == 'true'
      run: |
        echo "Linking Fonts..."
        mkdir -p /usr/share/fonts/truetype/
        ln -sf ~/.fonts/opentype/*.[to]tf /usr/share/fonts/truetype/
        echo "Reloading Font Cache..."
        fc-cache -f -v

    - name: Install dependencies
      run: |
        sudo apt-get update
        sudo apt-get install -qy groff html2text python3-cffi python3-brotli libpango-1.0-0 libharfbuzz0b libpangoft2-1.0-0 libxml2-dev libxml2-utils libxslt-dev
        echo "Installing pip + wheel..."
        python -m pip install --upgrade pip wheel
        echo "Installing test dependencies..."
        python -m pip install tox tox-gh-actions certifi decorator dict2xml pyflakes "pypdf>=4.1.0" "weasyprint==61.2" "pydyf<0.10.0"

    - name: Generate Valid Tests
      run: |
        make yestests || true
        cp -af tests/out/. tests/valid

    - name: Test with tox
      env:
        PLATFORM: ubuntu-latest
      run: tox

  tests-macos:
    name: Unit Tests (macOS)
    runs-on: macos-latest
    if: github.event_name == 'pull_request'

    strategy:
      matrix:
        python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']

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

    - name: Setup Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}

    - name: Fonts Cache
      id: cache-fonts-mac
      uses: pat-s/always-upload-cache@v2.1.5
      with:
        path: ~/fonts
        key: fonts-macos

    - name: Download Fonts
      run: |
        echo "Downloading xml2rfc-fonts"
        mkdir -p ~/fonts /Library/Fonts
        wget -q -O fonts.tar.gz https://github.com/ietf-tools/xml2rfc-fonts/archive/refs/tags/3.22.0.tar.gz
        tar zxf fonts.tar.gz -C ~/fonts
        mv ~/fonts/*/noto/* /Library/Fonts/
        mv ~/fonts/*/roboto_mono/* /Library/Fonts/

    - name: Install dependencies
      run: |
        brew install make diffutils
        # Install WeasyPrint 61.2
        brew tap-new --no-git custom/weasyprint
        brew extract --git-revision edb83fc7c8bb9987bdecb810e61281c5adc47c73 weasyprint custom/weasyprint
        brew install weasyprint@61.2
        echo "Installing pip + wheel..."
        python -m pip install --upgrade pip wheel
        echo "Installing test dependencies..."
        python -m pip install tox tox-gh-actions certifi decorator dict2xml pyflakes "pypdf>=4.1.0" "weasyprint==61.2" "pydyf<0.10.0"

    - name: Generate Valid Tests
      run: |
        export DYLD_FALLBACK_LIBRARY_PATH=/opt/homebrew/lib:$DYLD_FALLBACK_LIBRARY_PATH
        echo "/usr/local/opt/make/libexec/gnubin" >> $GITHUB_PATH
        make yestests || true
        cp -af tests/out/. tests/valid

    - name: Test with tox
      env:
        PLATFORM: macos-latest
      run: |
        export DYLD_FALLBACK_LIBRARY_PATH=/opt/homebrew/lib:$DYLD_FALLBACK_LIBRARY_PATH
        echo "/usr/local/opt/make/libexec/gnubin" >> $GITHUB_PATH
        env 'TOX_OVERRIDE=testenv.pass_env+=DYLD_FALLBACK_LIBRARY_PATH' tox

  tests-windows:
     name: Unit Tests (Windows)
     runs-on: windows-latest
     if: github.event_name == 'pull_request'

     strategy:
       matrix:
         python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']

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

     - name: Setup Python ${{ matrix.python-version }}
       uses: actions/setup-python@v5
       with:
         python-version: ${{ matrix.python-version }}

     - name: Install Python dependencies
       shell: pwsh
       run: |
         echo "C:\msys64\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH
         echo "Installing pip + wheel..."
         python -m pip install --upgrade pip wheel
         echo "Installing test dependencies..."
         python -m pip install . tox tox-gh-actions certifi decorator dict2xml pyflakes "pypdf>=4.10"

     - name: Run pytests
       env:
         PLATFORM: windows-latest
       run: tox -- pytests
