name: Docs Check

on:
  push:
    branches: ["**"]
    paths:
      - "**.md"
      - ".gitea/workflows/docs-check.yml"
  pull_request:
    branches: ["**"]
    paths:
      - "**.md"
      - ".gitea/workflows/docs-check.yml"

jobs:
  markdown-lint:
    name: Markdown lint
    runs-on: ubuntu-latest
    continue-on-error: true
    steps:
      - uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "22"

      - name: Install markdownlint-cli
        run: npm install -g markdownlint-cli

      - name: Lint all Markdown files
        run: markdownlint "**/*.md" --ignore node_modules

  mermaid-parse:
    name: Mermaid diagram parse check
    runs-on: ubuntu-latest
    continue-on-error: true
    steps:
      - uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "22"

      - name: Install mermaid and jsdom
        run: npm install mermaid jsdom

      - name: Extract and validate Mermaid diagrams
        run: |
          cat > check-mermaid.cjs << 'SCRIPT'
          const { JSDOM } = require('jsdom');
          const fs   = require('fs');
          const path = require('path');

          // Provide minimal browser globals so mermaid.parse() works in Node
          const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', { url: 'http://localhost' });
          globalThis.window   = dom.window;
          globalThis.document = dom.window.document;
          globalThis.DOMPurify = {
            addHook: () => {}, removeHook: () => {}, setConfig: () => {},
            sanitize: (s) => s, isValidAttribute: () => true,
          };

          function findMdFiles(dir) {
            const out = [];
            for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
              const full = path.join(dir, e.name);
              if (e.isDirectory() && e.name !== 'node_modules' && !e.name.startsWith('.'))
                out.push(...findMdFiles(full));
              else if (e.isFile() && e.name.endsWith('.md'))
                out.push(full);
            }
            return out;
          }

          import('./node_modules/mermaid/dist/mermaid.core.mjs').then(async (m) => {
            const mermaid = m.default;
            let errors = 0, total = 0;

            for (const mdFile of findMdFiles('.')) {
              const content = fs.readFileSync(mdFile, 'utf8');
              const blocks = [...content.matchAll(/^```mermaid\n([\s\S]*?)^```/gm)];
              if (!blocks.length) continue;
              console.log(`\nChecking ${mdFile} (${blocks.length} diagram(s))`);
              for (let i = 0; i < blocks.length; i++) {
                total++;
                const diagram = blocks[i][1].trim();
                try {
                  await mermaid.parse(diagram);
                  console.log(`  [OK]  diagram ${i + 1}`);
                } catch (err) {
                  const msg = String(err.message || err).split('\n')[0];
                  console.error(`  [FAIL] diagram ${i + 1}: ${msg}`);
                  console.log(`::warning file=${mdFile}::Mermaid diagram ${i + 1} failed: ${msg}`);
                  errors++;
                }
              }
            }

            console.log(`\nTotal: ${total}. Failures: ${errors}`);
            if (errors > 0) {
              console.log(`::warning::${errors} Mermaid diagram(s) failed to parse.`);
              process.exit(1);
            }
          }).catch(e => { console.error('Fatal:', e.message); process.exit(1); });
          SCRIPT
          node check-mermaid.cjs
