// Shared machinery for the pm2 install profiles (ecosystem.light.config.cjs,
// ecosystem.mac.light.config.cjs).
//
// A profile is a SUBSET of ecosystem.config.cjs, declared as names plus reasons. It never restates how
// a process is launched — `script` and `args` are read from the host file at load — because a
// hand-copied process list is exactly what failed here: the macOS list was written on 2026-07-28 and
// within days was starting a sidecar that had been split in two and pointing at a pty entry point that
// had moved. Neither failure said anything; the processes simply did not come up.
//
// So the rule is: ecosystem.config.cjs is the only place a launch command is written down, and a
// profile only decides which of them to run.
//
// Two consistency checks, both of which turn a silent breakage into a loud one at load:
//   1. a name the profile INCLUDES that the host no longer defines — the app was renamed or removed
//   2. an app the host defines that the profile neither includes nor excludes — a new sidecar, which
//      must be classified deliberately rather than defaulting to absent because nobody noticed
//
// The second is the one that matters over time. Without it, every sidecar added to the host silently
// stays out of every profile, and the profiles quietly stop meaning what their comments claim.

/**
 * @param {object} spec
 * @param {string} spec.file     this profile's filename, for error messages
 * @param {string[]} spec.include app names to run, in start order
 * @param {Record<string,string>} spec.excluded  app name → why it is not in this profile
 */
function defineProfile({ file, include, excluded }) {
  const full = require('./ecosystem.config.cjs');
  const byName = new Map(full.apps.map((app) => [app.name, app]));

  const missing = include.filter((name) => !byName.has(name));
  if (missing.length) {
    throw new Error(
      `${file}: ${missing.join(', ')} not found in ecosystem.config.cjs — the app was renamed or ` +
        `removed. Update this profile's include list.`,
    );
  }

  const unclassified = full.apps
    .map((app) => app.name)
    .filter((name) => !include.includes(name) && !(name in excluded));
  if (unclassified.length) {
    throw new Error(
      `${file}: ${unclassified.join(', ')} is in ecosystem.config.cjs but neither included nor ` +
        `excluded here. Add it to the include list, or to the excluded map with a reason.`,
    );
  }

  // `cwd` is pinned because Bun auto-loads .env from the working directory (and the pty sidecar does
  // `import 'dotenv/config'`). Without it, starting pm2 from anywhere but the repo root silently falls
  // back to PORT=5000 with no POSTGRES_URL. __dirname is the repo root — this file sits beside
  // ecosystem.config.cjs.
  return { apps: include.map((name) => ({ ...byName.get(name), cwd: __dirname })) };
}

module.exports = { defineProfile };
