#!/usr/bin/env node
/**
 * Builds toju-app/public/i18n/en.json from the base catalog plus extracted
 * labels from theme-registry and access-control constants.
 */
import { readFileSync, readdirSync, writeFileSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const repoRoot = resolve(__dirname, '..');
const catalogDir = resolve(repoRoot, 'toju-app/public/i18n/catalog');

function extractLabelDescriptionBlocks(source, blockPattern) {
  const entries = {};
  let match;

  while ((match = blockPattern.exec(source)) !== null) {
    const [, key, label, description] = match;
    entries[key] = { label, description };
  }

  return entries;
}

function extractThemeRegistry(source) {
  return extractLabelDescriptionBlocks(
    source,
    /key: '([^']+)',\s*\n\s*label: '((?:\\'|[^'])*)',\s*\n\s*description: '((?:\\'|[^'])*)',/g
  );
}

function extractPermissions(source) {
  return extractLabelDescriptionBlocks(
    source,
    /key: '([^']+)',\s*\n\s*label: '((?:\\'|[^'])*)',\s*\n\s*description: '((?:\\'|[^'])*)'/g
  );
}

function unescape(value) {
  return value.replace(/\\'/g, "'");
}

function deepMerge(target, source) {
  for (const [key, value] of Object.entries(source)) {
    if (value && typeof value === 'object' && !Array.isArray(value)) {
      target[key] ??= {};
      deepMerge(target[key], value);
      continue;
    }

    target[key] = value;
  }

  return target;
}

function mergeAtPath(catalog, pathSegments) {
  let target = catalog;

  for (const segment of pathSegments) {
    target[segment] ??= {};
    target = target[segment];
  }

  return target;
}

function mergeExtracted(catalog, extracted, prefix) {
  const target = mergeAtPath(catalog, prefix.split('.'));

  for (const [key, { label, description }] of Object.entries(extracted)) {
    target[key] ??= {};
    target[key].label = unescape(label);
    target[key].description = unescape(description);
  }
}

function loadCatalogFragments() {
  const catalog = {};
  const files = readdirSync(catalogDir)
    .filter((name) => name.endsWith('.json'))
    .sort();

  for (const file of files) {
    const fragment = JSON.parse(readFileSync(resolve(catalogDir, file), 'utf8'));
    deepMerge(catalog, fragment);
  }

  return catalog;
}

function main() {
  const themeRegistrySource = readFileSync(
    resolve(repoRoot, 'toju-app/src/app/domains/theme/domain/logic/theme-registry.logic.ts'),
    'utf8'
  );
  const permissionsSource = readFileSync(
    resolve(repoRoot, 'toju-app/src/app/domains/access-control/domain/constants/access-control.constants.ts'),
    'utf8'
  );

  const catalog = loadCatalogFragments();
  mergeExtracted(catalog, extractThemeRegistry(themeRegistrySource), 'theme.registry');
  mergeExtracted(catalog, extractPermissions(permissionsSource), 'permissions');

  const outputPath = resolve(repoRoot, 'toju-app/public/i18n/en.json');
  writeFileSync(outputPath, `${JSON.stringify(catalog, null, 2)}\n`, 'utf8');
  console.log(`Wrote ${outputPath}`);
}

main();
