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

const sourceCss = await readFile(
  path.join(repositoryRoot, 'contracts', 'phase9', 'tokens', 'semantic-tokens_v1.0.css'),
  'utf8',
);
const implementationCssPath = path.join(repositoryRoot, 'src', 'styles', 'tokens.css');
const implementationCss = await readFile(implementationCssPath, 'utf8');
const designTokens = JSON.parse(
  await readFile(
    path.join(repositoryRoot, 'src', 'contracts', 'phase9', 'design-tokens.json'),
    'utf8',
  ),
);
const errors = [];

if (sourceCss !== implementationCss)
  errors.push('Implementation tokens.css differs from Phase 9 source.');
const rawColors = new Set();
for (const scale of Object.values(designTokens.raw.color)) {
  for (const value of Object.values(scale)) rawColors.add(String(value).toLowerCase());
}

const applicationStyles = await walk(
  path.join(repositoryRoot, 'src'),
  (file) => file.endsWith('.css') && file !== implementationCssPath,
);
for (const file of applicationStyles) {
  const text = (await readFile(file, 'utf8')).toLowerCase();
  for (const color of rawColors) {
    if (text.includes(color))
      errors.push(`${path.relative(repositoryRoot, file)} embeds raw brand color ${color}.`);
  }
}
for (const required of [
  '--color-canvas',
  '--color-text',
  '--color-action-primary',
  '--color-focus',
]) {
  if (!implementationCss.includes(required)) errors.push(`Missing semantic token ${required}.`);
}

if (errors.length > 0) fail(errors);
else
  pass(
    'Phase 9 semantic tokens are unchanged and application styles contain no raw palette colors.',
  );
