#!/usr/bin/env node
// Makes the two ESM-only server dependencies loadable by the embedded Node 18
// (nodejs-mobile) runtime, which cannot require() ESM. Run AFTER
// `npm install` inside nodejs-assets/nodejs-project (re-run after any install).
//
//   • kysely (used: routes/categories.cts -> db/kysely.cts) — bundled to a
//     self-contained CommonJS file; its package entry is repointed at it.
//   • openid-client (UNUSED in single-user local mode, but eagerly require()'d
//     at boot via auth.cts/authOidc.cts -> oidcService.cts) — replaced with a
//     CommonJS stub so boot doesn't crash. Any actual use throws.
//
// Both are loaded on the web app (Node 22, native ESM); this only affects the
// on-device copy.

'use strict';

const fs = require('fs');
const path = require('path');
const esbuild = require('esbuild'); // from the mobile project's own node_modules

const PROJECT = path.join(__dirname, '..', 'nodejs-assets', 'nodejs-project');
const NM = path.join(PROJECT, 'node_modules');

function fail(msg) {
  console.error('prepare-local-mode-deps: ' + msg);
  process.exit(1);
}

// ── kysely → CommonJS ────────────────────────────────────────────────────────
(function bundleKysely() {
  const dir = path.join(NM, 'kysely');
  if (!fs.existsSync(dir)) fail('kysely not installed — run `npm install` in nodejs-project first.');

  const entry = path.join(dir, 'dist', 'index.js'); // ESM entry
  const outfile = path.join(dir, 'dist', 'index.cjs');
  esbuild.buildSync({
    entryPoints: [entry],
    bundle: true,
    format: 'cjs',
    platform: 'node',
    target: 'node18',
    outfile,
    logLevel: 'silent',
  });

  const pkgPath = path.join(dir, 'package.json');
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
  pkg.main = './dist/index.cjs';
  pkg.exports = {
    '.': { require: './dist/index.cjs', import: './dist/index.js', default: './dist/index.cjs' },
    './package.json': './package.json',
  };
  fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
  console.log('  kysely -> bundled to CommonJS (dist/index.cjs)');
})();

// ── openid-client → CommonJS stub ────────────────────────────────────────────
(function stubOpenidClient() {
  const dir = path.join(NM, 'openid-client');
  fs.mkdirSync(dir, { recursive: true });
  fs.writeFileSync(
    path.join(dir, 'package.json'),
    JSON.stringify({ name: 'openid-client', version: '0.0.0-local-stub', main: 'index.js' }, null, 2) + '\n',
  );
  fs.writeFileSync(
    path.join(dir, 'index.js'),
    "'use strict';\n" +
      '// Local-mode stub. OIDC/SSO is not available when running on-device.\n' +
      'function notSupported() { throw new Error("OIDC is not available in local mode"); }\n' +
      'module.exports = new Proxy({}, { get: function () { return notSupported; } });\n',
  );
  console.log('  openid-client -> CommonJS stub (OIDC disabled in local mode)');
})();

// ── ICU-less \p{} regex compatibility ────────────────────────────────────────
// nodejs-mobile's Node 18 ships WITHOUT ICU, so V8 cannot resolve Unicode
// property escapes (\p{...}) — any regex using them throws "Invalid property
// name" at compile time. path-to-regexp (express 5's router) uses
// \p{ID_Start}/\p{ID_Continue} at module load to validate route-param names,
// which crashes server boot. Rewrite to ASCII-safe classes; every route param
// in this app is ASCII (:id, :userId, …). (minimatch also contains \p{} but only
// as lazy POSIX-class strings that this app's globs never trigger — left as-is.)
(function patchPathToRegexp() {
  const f = path.join(NM, 'path-to-regexp', 'dist', 'index.js');
  if (!fs.existsSync(f)) return;
  let s = fs.readFileSync(f, 'utf8');
  const before = s;
  s = s.replace(/\\p\{ID_Start\}/g, 'a-zA-Z').replace(/\\p\{ID_Continue\}/g, 'a-zA-Z0-9');
  if (s !== before) {
    fs.writeFileSync(f, s);
    console.log('  path-to-regexp -> ASCII identifier regex (ICU-less \\p{} fix)');
  }
})();

console.log('prepare-local-mode-deps: done.');
