#!/usr/bin/env node
// LESS validator. Uses the less JS API (CJS, Node-16-friendly) so we
// don't depend on the lessc bin (ESM, requires Node ≥18).
//
// Usage: node tools/lint-less.cjs [files...]
//   defaults to styles/*.less when no args.

const fs = require('fs');
const path = require('path');
const less = require('less');

const root = path.resolve(__dirname, '..');

function findLessFiles() {
  const dir = path.join(root, 'styles');
  if (!fs.existsSync(dir)) return [];
  return fs.readdirSync(dir)
    .filter(f => f.endsWith('.less'))
    .map(f => path.join(dir, f));
}

async function check(file) {
  const rel = path.relative(root, file);
  const src = fs.readFileSync(file, 'utf8');

  // Stub the Atom ui-variables / syntax-variables imports — they only
  // exist inside Pulsar at runtime. We don't need their values, we just
  // need the LESS parser to accept the file.
  const stub = `
    @ui-size: 12px;
    @base-background-color: #2b2b2b;
    @base-border-color: #444;
    @text-color: #ccc;
    @text-color-subtle: #888;
    @text-color-highlight: #fff;
    @text-color-info: #6cf;
    @text-color-success: #6c6;
    @text-color-warning: #fc6;
    @background-color-warning: #c80;
    @font-family: monospace;
  `;
  // Drop the @import lines that pull Atom-only files.
  const stripped = src.replace(/^@import\s+["'](ui-variables|syntax-variables)["'];?\s*$/gm, '');
  const input = stub + '\n' + stripped;

  try {
    await less.render(input, { math: 'strict', filename: file });
    console.log(`  \x1b[32m✓\x1b[0m ${rel}`);
    return true;
  } catch (e) {
    const line = e.line || '?';
    const col  = e.column || '?';
    console.log(`  \x1b[31m✘\x1b[0m ${rel}`);
    console.log(`    \x1b[31m${e.type || 'Error'}\x1b[0m at ${line}:${col} — ${e.message || e}`);
    if (e.extract) {
      const ln = e.line - 1;
      e.extract.forEach((l, i) => {
        if (l == null) return;
        const marker = (i === 1) ? '\x1b[31m▶\x1b[0m' : ' ';
        console.log(`    ${marker} ${(ln + i).toString().padStart(4)} | ${l}`);
      });
    }
    return false;
  }
}

(async () => {
  const args = process.argv.slice(2);
  const files = args.length ? args : findLessFiles();
  if (!files.length) { console.log('no .less files'); process.exit(0); }

  console.log(`== LESS lint (${files.length} file${files.length > 1 ? 's' : ''}) ==`);
  let allOk = true;
  for (const f of files) {
    const ok = await check(f);
    if (!ok) allOk = false;
  }
  process.exit(allOk ? 0 : 1);
})();
