import { readFile, stat } from 'node:fs/promises';
import path from 'node:path';
import { fail, pass, repositoryRoot } from './lib.mjs';

const manifest = JSON.parse(
  await readFile(
    path.join(repositoryRoot, 'src', 'contracts', 'phase9', 'route-manifest.json'),
    'utf8',
  ),
);
const errors = [];
const requiredLocales = ['en', 'fr', 'ar'];
const ids = new Set();

if (JSON.stringify(manifest.locales) !== JSON.stringify(requiredLocales)) {
  errors.push('Route locales must remain exactly en, fr, ar.');
}
for (const route of manifest.routes) {
  if (ids.has(route.id)) errors.push(`Duplicate route ID: ${route.id}`);
  ids.add(route.id);
  for (const locale of requiredLocales) {
    if (typeof route.slugs[locale] !== 'string') errors.push(`${route.id} has no ${locale} slug.`);
  }
}
for (const locale of requiredLocales) {
  if (!manifest.hreflang.values.includes(locale)) errors.push(`hreflang omits ${locale}.`);
}
if (manifest.hreflang.xDefaultLocale !== 'en') errors.push('x-default must resolve to English.');
if (manifest.switching.dropUnknownQuery !== true) {
  errors.push('Unknown query parameters must be dropped.');
}

for (const routeFile of [
  'src/app/[locale]/page.tsx',
  'src/app/[locale]/[slug]/page.tsx',
  'src/app/[locale]/not-found.tsx',
]) {
  try {
    await stat(path.join(repositoryRoot, routeFile));
  } catch {
    errors.push(`Runtime route implementation missing: ${routeFile}`);
  }
}

if (errors.length > 0) fail(errors);
else
  pass(
    `${manifest.routes.length} route IDs have complete locale, runtime, hash, query, ` +
      'and hreflang contracts.',
  );
