#!/usr/bin/env node
// check-architecture-skill-no-drift.mjs — prepublishOnly gate.
//
// The per-brand platform-architecture skill body is a generated artefact.
// Source: docs/public/llms-full.<brand>.txt (emitted by copy-docs.mjs).
// Generator: maxy-code/scripts/assemble-architecture-skill.mjs --brand <brand>.
//
// For brand=maxy-code, the gate also asserts byte-equality with the
// checked-in skill source at platform/plugins/admin/skills/platform-architecture/SKILL.md
// (back-compat with the existing release flow).
//
// For other brands, the gate asserts the assembled cache body exists and
// contains the brand product name + the catalogue-boundary sentence.
//
// Usage:
//   node platform/scripts/check-architecture-skill-no-drift.mjs                  # all brands
//   node platform/scripts/check-architecture-skill-no-drift.mjs --brand maxy-code
//   node platform/scripts/check-architecture-skill-no-drift.mjs --brand realagent-code

import { readFileSync, existsSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process';
import { assemble } from '../../scripts/assemble-architecture-skill.mjs';

const __dirname = dirname(fileURLToPath(import.meta.url));
const MAXY_CODE_ROOT = resolve(__dirname, '..', '..');
const REPO_ROOT = resolve(MAXY_CODE_ROOT, '..');
const COPY_DOCS = resolve(REPO_ROOT, 'docs/scripts/copy-docs.mjs');

const args = process.argv.slice(2);
const brandIdx = args.indexOf('--brand');
const REQUESTED_BRAND = brandIdx === -1 ? null : args[brandIdx + 1];

const CATALOGUE_BOUNDARY_SUBSTRING = 'not evidence of what is installed on the current account';

const BRANDS = [
  {
    key: 'maxy-code',
    productName: 'Maxy',
    docsUrl: 'https://docs.getmaxy.com',
    sourceSkillPath: resolve(
      MAXY_CODE_ROOT,
      'platform/plugins/admin/skills/platform-architecture/SKILL.md',
    ),
  },
  {
    key: 'realagent-code',
    productName: 'Real Agent',
    docsUrl: 'https://docs.realagent.network',
    sourceSkillPath: null,
  },
];

function fail(msg) {
  console.error(`[check-architecture-skill-no-drift] ERROR: ${msg}`);
  process.exit(1);
}

if (!existsSync(COPY_DOCS)) fail(`docs mirror script missing: ${COPY_DOCS}`);

execFileSync('node', [COPY_DOCS], { stdio: 'pipe' });

const ASSEMBLER = resolve(MAXY_CODE_ROOT, 'scripts/assemble-architecture-skill.mjs');

const brandsToCheck = REQUESTED_BRAND
  ? BRANDS.filter((b) => b.key === REQUESTED_BRAND)
  : BRANDS;

if (REQUESTED_BRAND && brandsToCheck.length === 0) {
  fail(`unknown brand: ${REQUESTED_BRAND}`);
}

for (const brand of brandsToCheck) {
  const corpus = resolve(REPO_ROOT, `docs/public/llms-full.${brand.key}.txt`);
  if (!existsSync(corpus)) fail(`expected ${corpus} after running copy-docs.mjs`);

  // Re-run assembler for this brand. The assembler writes the cache file;
  // we then compare its body to a fresh in-process assemble() call to catch
  // drift between the assembler module and the cache write.
  execFileSync('node', [ASSEMBLER, '--brand', brand.key], { stdio: 'pipe' });

  const body = readFileSync(corpus, 'utf8');
  const expected = assemble(body, {
    productName: brand.productName,
    brand: brand.key,
    docsUrl: brand.docsUrl,
  });

  if (!expected.includes(CATALOGUE_BOUNDARY_SUBSTRING)) {
    fail(`brand=${brand.key}: assembled body missing catalogue-boundary sentence`);
  }
  if (!expected.includes(brand.productName)) {
    fail(`brand=${brand.key}: assembled body missing product name ${brand.productName}`);
  }

  if (brand.sourceSkillPath) {
    if (!existsSync(brand.sourceSkillPath)) {
      fail(
        `brand=${brand.key}: source skill missing at ${brand.sourceSkillPath}; ` +
          `run \`node maxy-code/scripts/assemble-architecture-skill.mjs\``,
      );
    }
    const actual = readFileSync(brand.sourceSkillPath, 'utf8');
    if (expected !== actual) {
      fail(
        `brand=${brand.key}: ${brand.sourceSkillPath} out of sync. ` +
          `Run \`node maxy-code/scripts/assemble-architecture-skill.mjs\` and commit.`,
      );
    }
  }

  console.log(`[check-architecture-skill-no-drift] ok brand=${brand.key} (${expected.length} bytes)`);
}
