name: Latest commit

env:
  CACHE_VERSION: 1
  DEFAULT_PYTHON: "3.14"
  PREK_HOME: ~/.cache/prek
  VENV: venv

on:
  schedule:
    - cron: "2 4 * * 0"  # weekly
  workflow_dispatch:
  push:
# pull_request:

jobs:
  # Check shellscripts
  shellcheck:
    name: Shellcheck
    runs-on: ubuntu-latest
    steps:
      - name: Check out committed code
        uses: actions/checkout@v6
      - name: Run ShellCheck
        uses: ludeeus/action-shellcheck@master

  ruff:
    runs-on: ubuntu-latest
    name: Ruff check and force
    steps:
      - name: Check out committed code
        uses: actions/checkout@v6
        with:
          persist-credentials: false
      - name: Use python
        uses: actions/setup-python@v6
        with:
          python-version: ${{ env.DEFAULT_PYTHON }}
      - name: Prepare python
        run: |
          pip install uv
          uv venv --seed venv
          . venv/bin/activate
          uv pip install ruff -r requirements.txt -r requirements-test.txt
      - name: Ruff (with fix)
        run: |
          . venv/bin/activate
          ruff check airos/ tests/
      - name: If needed, commit ruff changes to the pull request
        if: failure()
        run: |
          . venv/bin/activate
          ruff format airos/ tests/
          git config --global user.name 'autoruff'
          git config --global user.email 'airos@users.noreply.github.com'
          git remote set-url origin https://x-access-token:${{ secrets.PAT_CT }}@github.com/$GITHUB_REPOSITORY
          git checkout $GITHUB_HEAD_REF
          git commit -am "fixup: ${GITHUB_REF##*/} Python code fixed using ruff"
          git push origin ${GITHUB_REF##*/}

  commitcheck:
    runs-on: ubuntu-latest
    name: Check commit
    needs:
      - ruff
    steps:
      - name: Check out committed code
        uses: actions/checkout@v6
      - name: Use python
        uses: actions/setup-python@v6
        with:
          python-version: ${{ env.DEFAULT_PYTHON }}
      - name: Prepare python
        run: |
          pip install uv
          uv venv --seed venv
          . venv/bin/activate
          uv pip install prek -r requirements.txt -r requirements-test.txt
          prek install
      - name: Full prek (pre-commit)
        run: |
          . venv/bin/activate
          SKIP=no-commit-to-branch prek run --show-diff-on-failure --color=always --all-files

  pytest:
    runs-on: ubuntu-latest
    name: Run pytest using Python ${{ matrix.python-version }}
    needs:
      - ruff
      - commitcheck
    strategy:
      matrix:
        python-version: ["3.13", "3.14"]
    steps:
      - name: Check out committed code
        uses: actions/checkout@v6
      - name: Use python ${{matrix.python-version}}
        uses: actions/setup-python@v6
        with:
          python-version: ${{matrix.python-version}}
      - name: Prepare python
        run: |
          pip install uv
          uv venv --seed venv
          . venv/bin/activate
          uv pip install -r requirements.txt -r requirements-test.txt
      - name: Run all tests
        run: |
          . venv/bin/activate
          pytest --log-level info tests/ --cov='airos/'
      - name: Upload coverage artifact
        uses: actions/upload-artifact@v6
        with:
          name: coverage-${{ matrix.python-version }}
          path: .coverage
          if-no-files-found: error
          include-hidden-files: true

  mypy:
    runs-on: ubuntu-latest
    name: Run mypy
    needs:
      - ruff
      - pytest
    steps:
      - name: Check out committed code
        uses: actions/checkout@v6
        with:
          persist-credentials: false
      - name: Use python
        uses: actions/setup-python@v6
        with:
          python-version: ${{ env.DEFAULT_PYTHON }}
      - name: Prepare python
        run: |
          pip install uv
          uv venv --seed venv
          . venv/bin/activate
          uv pip install -r requirements.txt -r requirements-test.txt
      - name: Run mypy
        run: |
          . venv/bin/activate
          pip list | grep -i mypy
          mypy airos/

  coverage:
    name: Process test coverage
    runs-on: ubuntu-latest
    needs:
      - ruff
      - pytest
      - mypy
    steps:
      - name: Check out committed code
        uses: actions/checkout@v6
      - name: Use python
        uses: actions/setup-python@v6
        with:
          python-version: ${{ env.DEFAULT_PYTHON }}
      - name: Prepare python
        run: |
          pip install uv
          uv venv --seed venv
          . venv/bin/activate
          uv pip install -r requirements.txt -r requirements-test.txt
      - name: Download all coverage artifacts
        uses: actions/download-artifact@v7
        with:
          pattern: coverage-*
          merge-multiple: true
          path: ${{ github.workspace }}/artifacts
      - name: Combine coverage results
        run: |
          . venv/bin/activate
          coverage combine artifacts/.coverage*
          coverage report --fail-under=80
          coverage xml
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v5
        env:
          CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
          slug: CoMPaTech/python-airos

  test-publishing:
    name: Build and publish Python 🐍 distributions 📦 to TestPyPI
    runs-on: ubuntu-latest
    environment: testpypi
    permissions:
        id-token: write
    needs:
      - coverage
      # - mypy
    steps:
      - name: Check out committed code
        uses: actions/checkout@v6
      - name: Use python
        uses: actions/setup-python@v6
        with:
          python-version: ${{ env.DEFAULT_PYTHON }}
      - name: Prepare python
        run: |
          pip install uv
          uv venv --seed venv
          . venv/bin/activate
          uv pip install toml
      - name: Check for existing package on TestPyPI
        id: check_package
        run: |
          . venv/bin/activate
          PACKAGE_VERSION=$(python -c "import toml; print(toml.load('pyproject.toml')['project']['version'])")
          PACKAGE_NAME=$(python -c "import toml; print(toml.load('pyproject.toml')['project']['name'])")
          echo "Checking for package: $PACKAGE_NAME==$PACKAGE_VERSION"

          if curl -s "https://test.pypi.org/pypi/$PACKAGE_NAME/json" | jq -r '.releases | keys[]' | grep -q "^$PACKAGE_VERSION$"; then
            echo "Package version already exists. Skipping upload."
            echo "should_publish=false" >> $GITHUB_OUTPUT
          else
            echo "Package version does not exist. Proceeding with upload."
            echo "should_publish=true" >> $GITHUB_OUTPUT
          fi
      - name: Build
        if: steps.check_package.outputs.should_publish == 'true'
        run: |
          . venv/bin/activate
          uv build
      - name: Publish distribution 📦 to TestPyPI
        if: steps.check_package.outputs.should_publish == 'true'
        run: |
          . venv/bin/activate
          uv publish --publish-url https://test.pypi.org/legacy/


  complexity:
    name: Process test complexity
    runs-on: ubuntu-latest
    needs:
      - coverage
    steps:
      - name: Check out committed code
        uses: actions/checkout@v6
      - name: Use python
        uses: actions/setup-python@v6
        with:
          python-version: ${{ env.DEFAULT_PYTHON }}
      - name: Prepare python
        run: |
          pip install uv
          uv venv --seed venv
          . venv/bin/activate
          uv pip install -r requirements.txt -r requirements-test.txt
      - name: Run complexity report (click to view details)
        run: |
          . venv/bin/activate
          echo "Showing complexity higher or equal to 'C'"
          radon cc airos/ tests/ -s -nc --no-assert
