#!/usr/bin/env node
// Transpiles the Bill Tracker server's TypeScript sources to plain CommonJS for
// the embedded Node 18.20.4 runtime (nodejs-mobile). Node 18 runs modern JS
// syntax natively, so — unlike the old Node-12 pass — this ONLY strips
// TypeScript; it does not rewrite dependency syntax and does not touch
// node_modules (their JS runs as-is on Node 18).
//
// The server is CommonJS-with-TS: files use require()/module.exports plus
// `import type`/`as typeof import()` for types, and require() each other with
// EXPLICIT `.cts`/`.mts` extensions (115 .cts + 40 .mts call sites). We therefore
// transpile each .cts/.mts file IN PLACE, keeping its original name: esbuild
// strips the types and emits CJS, and Node 18's CommonJS loader loads unknown
// extensions (.cts/.mts) through the default `.js` handler as CommonJS — so every
// explicit-extension require() path keeps resolving with zero path rewriting.
//
// Usage: node transpile-node18.js <serverDir> [<dir> ...]

'use strict';

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

const SKIP_DIRS = new Set(['.bin', 'node_modules', 'dist']);

function loaderFor(file) {
  if (/\.(cts|mts|ts)$/.test(file)) return 'ts';
  if (/\.(cjs|js)$/.test(file)) return 'js';
  return null;
}

function walk(dir, cb) {
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
    if (SKIP_DIRS.has(entry.name)) continue;
    if (entry.isSymbolicLink()) continue;
    const full = path.join(dir, entry.name);
    if (entry.isDirectory()) walk(full, cb);
    else if (loaderFor(entry.name)) cb(full);
  }
}

let count = 0;
let failed = 0;
for (const dir of process.argv.slice(2)) {
  if (!fs.existsSync(dir)) continue;
  walk(dir, (file) => {
    const src = fs.readFileSync(file, 'utf8');
    let out;
    try {
      out = esbuild.transformSync(src, {
        loader: loaderFor(file),
        format: 'cjs',
        target: 'node18',
        sourcefile: file,
      }).code;
    } catch (err) {
      console.error(`FAILED ${file}: ${err.message.split('\n')[0]}`);
      failed++;
      return;
    }
    if (out !== src) {
      fs.writeFileSync(file, out);
      count++;
    }
  });
}

if (failed) {
  console.error(`Transpile finished with ${failed} failure(s).`);
  process.exit(1);
}
console.log(`Transpiled ${count} file(s) to CommonJS for Node 18.`);
