name: CI

on:
  push:
    branches: [main]
    tags: ["*"]
  pull_request:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
  # ── Lint, Build & Test on macOS and Linux ──────────────────────
  build:
    name: ${{ matrix.name }}
    runs-on: ${{ matrix.runner }}
    container: ${{ matrix.container }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - name: "macOS"
            runner: macos-15
            container: ""
            install-swiftlint: brew install swiftlint
          - name: "Linux"
            runner: ubuntu-latest
            container: swift:6.0
            install-swiftlint: |
              apt-get update && apt-get install -y curl unzip
              SWIFTLINT_VERSION="0.58.2"
              curl -fsSL "https://github.com/realm/SwiftLint/releases/download/${SWIFTLINT_VERSION}/swiftlint_linux.zip" -o swiftlint.zip
              unzip -o swiftlint.zip -d /usr/local/bin
              chmod +x /usr/local/bin/swiftlint
              rm swiftlint.zip

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

      - name: Install SwiftLint
        run: ${{ matrix.install-swiftlint }}

      - name: Lint
        run: swiftlint

      - name: Build
        env:
          DISABLE_SWIFTLINT: "1"
        run: swift build

      - name: Test
        env:
          DISABLE_SWIFTLINT: "1"
        run: swift test

  # ── Update test count badge in README (main only) ─────────────
  update-badge:
    name: Update test badge
    needs: build
    runs-on: macos-15
    if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main'
    permissions:
      contents: write
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          ref: main

      - name: Count tests and suites
        id: counts
        run: |
          TESTS=$(grep -r '@Test\b' Tests/ --include='*.swift' | wc -l | tr -d ' ')
          SUITES=$(grep -r '@Suite\b' Tests/ --include='*.swift' | wc -l | tr -d ' ')
          echo "tests=$TESTS" >> "$GITHUB_OUTPUT"
          echo "suites=$SUITES" >> "$GITHUB_OUTPUT"
          echo "Found $TESTS tests in $SUITES suites"

      - name: Update README badge and counts
        env:
          TESTS: ${{ steps.counts.outputs.tests }}
          SUITES: ${{ steps.counts.outputs.suites }}
        run: |
          # Badge: Tests-NNN_passing
          sed -i '' "s/Tests-[0-9]*_passing/Tests-${TESTS}_passing/" README.md
          # Project structure: NNN tests across NN test suites
          sed -i '' "s/[0-9]* tests across [0-9]* test suites/${TESTS} tests across ${SUITES} test suites/" README.md
          # Developer notes: All NNN tests run in parallel
          sed -i '' "s/All [0-9]* tests run/All ${TESTS} tests run/" README.md

      - name: Commit if changed
        run: |
          git diff --quiet README.md && echo "No changes" && exit 0
          git config user.name "Frank Gregor"
          git config user.email "phranck@mac.com"
          git add README.md
          # [skip ci] prevents the push from triggering another workflow run
          git commit -m "Chore: Update test count badge to ${{ steps.counts.outputs.tests }} tests [skip ci]"
          git push

  # ── Landing Page + DocC (macOS only, main/tag only) ────────────
  build-docs:
    name: Build Landing Page & DocC
    needs: build
    runs-on: macos-15
    if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Determine version
        id: version
        run: |
          # Use tag name if triggered by a tag push, otherwise latest tag
          if [[ "$GITHUB_REF" == refs/tags/* ]]; then
            VERSION="${GITHUB_REF#refs/tags/}"
          else
            VERSION=$(git describe --tags --abbrev=0 2>/dev/null || echo "0.1.0")
          fi
          # Strip leading 'v' if present (v1.2.3 -> 1.2.3)
          VERSION="${VERSION#v}"
          echo "version=$VERSION" >> "$GITHUB_OUTPUT"
          echo "Resolved version: $VERSION"

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "22"
          cache: "npm"
          cache-dependency-path: docs/package-lock.json

      - name: Build landing page
        working-directory: docs
        env:
          TUIKIT_VERSION: ${{ steps.version.outputs.version }}
          PUBLIC_GITHUB_TOKEN: ${{ secrets.DASHBOARD_GITHUB_TOKEN }}
        run: |
          npm ci
          npm run build

      - name: Build DocC documentation
        env:
          DISABLE_SWIFTLINT: "1"
        run: |
          swift package --allow-writing-to-directory docs-output \
            generate-documentation \
            --target TUIkit \
            --output-path docs-output \
            --transform-for-static-hosting

      - name: Assemble site
        run: |
          cp -r docs/dist/* docs-output/

      - name: Add CNAME for custom domain
        run: echo "tuikit.layered.work" > docs-output/CNAME

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: docs-output

  # ── Deploy to GitHub Pages ─────────────────────────────────────
  deploy:
    name: Deploy to GitHub Pages
    needs: build-docs
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4
