name: CI

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

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

permissions:
  contents: read

env:
  NPM_CONFIG_AUDIT: "false"
  NPM_CONFIG_FUND: "false"

jobs:
  unit-tests:
    name: Unit Tests (Node ${{ matrix.node-version }})
    runs-on: ubuntu-latest
    timeout-minutes: 25
    strategy:
      fail-fast: false
      matrix:
        node-version: ["20.x", "22.x"]
    steps:
      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          persist-credentials: false

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
        with:
          node-version: ${{ matrix.node-version }}
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Import knowledge base
        run: npm run import:bottobot

      - name: Test
        run: npm test

  build-package:
    name: Build and MCPB Package
    runs-on: ubuntu-latest
    timeout-minutes: 20
    steps:
      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          persist-credentials: false

      - name: Use Node.js 20.x
        uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
        with:
          node-version: 20.x
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Import knowledge base
        run: npm run import:bottobot

      - name: Build
        run: npm run build

      - name: Build .mcpb bundle
        run: npm run build:mcpb

  bridge-tests:
    name: Python Bridge Tests
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          persist-credentials: false

      - name: Test bridge
        run: python3 -m unittest discover -s td/tests

  raw-exec-off-smoke:
    name: Raw Exec OFF Smoke
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          persist-credentials: false

      - name: Use Node.js 22.x
        uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
        with:
          node-version: 22.x
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Smoke
        env:
          TDMCP_RAW_PYTHON: "off"
        run: node scripts/run-vitest.mjs run tests/smoke/execOff.test.ts

  creative-rag-multilingual-smoke:
    name: Creative RAG Multilingual Smoke
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          persist-credentials: false

      - name: Use Node.js 22.x
        uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
        with:
          node-version: 22.x
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Import knowledge base
        run: npm run import:bottobot

      - name: Smoke index with swapped embedding model
        env:
          TDMCP_RAG_EMBED_MODEL: bge-m3
        run: node scripts/run-vitest.mjs run tests/unit/creativeRag/ -t "embedding model"

  coverage:
    name: Coverage Gate
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          persist-credentials: false

      - name: Use Node.js 22.x
        uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
        with:
          node-version: 22.x
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Import knowledge base
        run: npm run import:bottobot

      - name: Test + coverage gate
        run: npm run test:coverage

  ci-success:
    name: CI Success
    runs-on: ubuntu-latest
    timeout-minutes: 5
    if: ${{ always() }}
    needs:
      - unit-tests
      - build-package
      - bridge-tests
      - raw-exec-off-smoke
      - creative-rag-multilingual-smoke
      - coverage
    env:
      UNIT_TESTS: ${{ needs.unit-tests.result }}
      BUILD_PACKAGE: ${{ needs.build-package.result }}
      BRIDGE_TESTS: ${{ needs.bridge-tests.result }}
      RAW_EXEC_OFF_SMOKE: ${{ needs.raw-exec-off-smoke.result }}
      CREATIVE_RAG_SMOKE: ${{ needs.creative-rag-multilingual-smoke.result }}
      COVERAGE: ${{ needs.coverage.result }}
    steps:
      - name: Check required CI jobs
        run: |
          set -euo pipefail
          failed=0
          for item in \
            "unit-tests=${UNIT_TESTS}" \
            "build-package=${BUILD_PACKAGE}" \
            "bridge-tests=${BRIDGE_TESTS}" \
            "raw-exec-off-smoke=${RAW_EXEC_OFF_SMOKE}" \
            "creative-rag-multilingual-smoke=${CREATIVE_RAG_SMOKE}" \
            "coverage=${COVERAGE}"
          do
            name="${item%%=*}"
            result="${item#*=}"
            echo "$name: $result"
            if [ "$result" != "success" ]; then
              failed=1
            fi
          done
          exit "$failed"
