name: CI

on:
  pull_request:
    branches: [main]

# Cancel previous runs for the same PR / branch
concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: true

jobs:
  # ── 1. Install dependencies ────────────────────────────────
  install:
    name: Install
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: "22"

      - name: Cache node_modules
        uses: actions/cache@v4
        id: cache-deps
        with:
          path: node_modules
          key: deps-${{ runner.os }}-${{ hashFiles('package.json') }}

      - name: npm install
        if: steps.cache-deps.outputs.cache-hit != 'true'
        run: npm install --ignore-scripts

  # ── 2. Pack validation ─────────────────────────────────────
  pack:
    name: Pack
    needs: install
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: "22"

      - name: Restore node_modules
        uses: actions/cache@v4
        with:
          path: node_modules
          key: deps-${{ runner.os }}-${{ hashFiles('package.json') }}

      - name: npm pack (dry-run)
        run: npm pack --dry-run

      - name: npm pack
        run: npm pack

      - name: Upload .tgz artifact
        uses: actions/upload-artifact@v4
        with:
          name: package-tarball
          path: "*.tgz"
          retention-days: 7

  # ── 5. Plugin manifest validation ──────────────────────────
  manifest:
    name: Manifest
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Validate openclaw.plugin.json
        run: |
          echo "── Checking openclaw.plugin.json exists ──"
          test -f openclaw.plugin.json || { echo "❌ openclaw.plugin.json not found"; exit 1; }

          echo "── Checking valid JSON ──"
          node -e "JSON.parse(require('fs').readFileSync('openclaw.plugin.json','utf8'))" || { echo "❌ Invalid JSON"; exit 1; }

          echo "── Checking required fields ──"
          node -e "
            const m = JSON.parse(require('fs').readFileSync('openclaw.plugin.json','utf8'));
            const errors = [];
            if (!m.id || typeof m.id !== 'string') errors.push('missing or invalid \"id\"');
            if (m.configSchema && typeof m.configSchema !== 'object') errors.push('\"configSchema\" must be an object');
            if (errors.length) { console.error('❌ Manifest errors:', errors.join(', ')); process.exit(1); }
            console.log('✅ id:', m.id);
            if (m.name) console.log('   name:', m.name);
            if (m.configSchema) console.log('   configSchema: present (' + Object.keys(m.configSchema.properties || {}).length + ' top-level props)');
          "

          echo "── Checking package.json openclaw metadata ──"
          node -e "
            const pkg = JSON.parse(require('fs').readFileSync('package.json','utf8'));
            const oc = pkg.openclaw || {};
            const errors = [];
            if (!oc.extensions || !oc.extensions.length) errors.push('missing openclaw.extensions');
            if (!oc.compat?.pluginApi) errors.push('missing openclaw.compat.pluginApi');
            if (!oc.build?.openclawVersion) errors.push('missing openclaw.build.openclawVersion');
            if (errors.length) { console.error('❌ Package metadata errors:', errors.join(', ')); process.exit(1); }
            console.log('✅ openclaw metadata OK');
            console.log('   pluginApi:', oc.compat.pluginApi);
            console.log('   openclawVersion:', oc.build.openclawVersion);
          "

  # ── 6. Package size guard ──────────────────────────────────
  size:
    name: Size Guard
    needs: pack
    runs-on: ubuntu-latest
    steps:
      - name: Download tarball
        uses: actions/download-artifact@v4
        with:
          name: package-tarball

      - name: Check package size
        run: |
          TGZ=$(ls *.tgz | head -1)
          SIZE=$(stat -c%s "$TGZ" 2>/dev/null || stat -f%z "$TGZ")
          SIZE_KB=$((SIZE / 1024))
          MAX_KB=512

          echo "📦 Package: $TGZ"
          echo "   Size: ${SIZE_KB} KB (limit: ${MAX_KB} KB)"

          if [ "$SIZE_KB" -gt "$MAX_KB" ]; then
            echo "❌ Package exceeds ${MAX_KB} KB size limit!"
            echo "   Consider checking if large files were accidentally included."
            exit 1
          else
            echo "✅ Size OK"
          fi
