/**
 * Verification test for Self-Hosted Fonts (Task 3)
 *
 * Checks that:
 * 1. 8 woff2 font files exist in src/fonts/
 * 2. src/styles/fonts.css exists with 8 @font-face declarations
 * 3. Each @font-face has correct font-family, weight, style, src, font-display
 * 4. src URLs use relative paths to ../fonts/
 */
import { readFileSync, existsSync, statSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const root = join(__dirname, '..');

let passed = 0;
let failed = 0;

function assert(condition, message) {
  if (condition) {
    console.log(`  ✓ ${message}`);
    passed++;
  } else {
    console.error(`  ✗ ${message}`);
    failed++;
  }
}

// === 1. Font files exist in src/fonts/ ===
console.log('\n1. Font files exist in src/fonts/');
const expectedFonts = [
  'source-serif-4-400.woff2',
  'source-serif-4-600.woff2',
  'source-serif-4-400-italic.woff2',
  'inter-400.woff2',
  'inter-500.woff2',
  'inter-600.woff2',
  'inter-700.woff2',
  'jetbrains-mono-400.woff2',
];

for (const font of expectedFonts) {
  const fontPath = join(root, 'src/fonts', font);
  const exists = existsSync(fontPath);
  assert(exists, `src/fonts/${font} exists`);
  if (exists) {
    const stat = statSync(fontPath);
    assert(stat.size > 1000, `src/fonts/${font} is a real font file (${stat.size} bytes)`);
  }
}

// === 2. fonts.css exists ===
console.log('\n2. fonts.css exists');
const fontsCssPath = join(root, 'src/styles/fonts.css');
assert(existsSync(fontsCssPath), 'src/styles/fonts.css exists');

if (!existsSync(fontsCssPath)) {
  console.log('\nfonts.css not found, skipping remaining tests.');
  console.log(`\n${'='.repeat(40)}`);
  console.log(`Results: ${passed} passed, ${failed} failed out of ${passed + failed}`);
  process.exit(1);
}

const css = readFileSync(fontsCssPath, 'utf8');

// === 3. Has 8 @font-face declarations ===
console.log('\n3. @font-face count');
const fontFaceBlocks = css.match(/@font-face\s*\{[^}]+\}/g);
const fontFaceCount = fontFaceBlocks ? fontFaceBlocks.length : 0;
assert(fontFaceCount === 8, `has exactly 8 @font-face declarations (found ${fontFaceCount})`);

// === 4. Source Serif 4 declarations (prose voice) ===
console.log('\n4. Source Serif 4 declarations (prose voice)');
// Regular 400
assert(
  css.includes("font-family: 'Source Serif 4'") || css.includes('font-family: "Source Serif 4"'),
  "has font-family: 'Source Serif 4'"
);
// Check for 400 normal
const ss4_400_block = fontFaceBlocks?.find(
  (b) =>
    (b.includes("'Source Serif 4'") || b.includes('"Source Serif 4"')) &&
    b.includes('font-weight: 400') &&
    b.includes('font-style: normal')
);
assert(!!ss4_400_block, 'Source Serif 4 400 normal declaration exists');
// Check for 600 normal
const ss4_600_block = fontFaceBlocks?.find(
  (b) =>
    (b.includes("'Source Serif 4'") || b.includes('"Source Serif 4"')) &&
    b.includes('font-weight: 600') &&
    b.includes('font-style: normal')
);
assert(!!ss4_600_block, 'Source Serif 4 600 normal declaration exists');
// Check for 400 italic
const ss4_400i_block = fontFaceBlocks?.find(
  (b) =>
    (b.includes("'Source Serif 4'") || b.includes('"Source Serif 4"')) &&
    b.includes('font-weight: 400') &&
    b.includes('font-style: italic')
);
assert(!!ss4_400i_block, 'Source Serif 4 400 italic declaration exists');

// === 5. Inter declarations (structure voice) ===
console.log('\n5. Inter declarations (structure voice)');
const interWeights = [400, 500, 600, 700];
for (const weight of interWeights) {
  const interBlock = fontFaceBlocks?.find(
    (b) =>
      (b.includes("'Inter'") || b.includes('"Inter"')) &&
      b.includes(`font-weight: ${weight}`) &&
      b.includes('font-style: normal')
  );
  assert(!!interBlock, `Inter ${weight} normal declaration exists`);
}

// === 6. JetBrains Mono declaration (evidence voice) ===
console.log('\n6. JetBrains Mono declaration (evidence voice)');
const jbBlock = fontFaceBlocks?.find(
  (b) =>
    (b.includes("'JetBrains Mono'") || b.includes('"JetBrains Mono"')) &&
    b.includes('font-weight: 400') &&
    b.includes('font-style: normal')
);
assert(!!jbBlock, 'JetBrains Mono 400 normal declaration exists');

// === 7. All declarations use format('woff2') ===
console.log("\n7. All use format('woff2')");
if (fontFaceBlocks) {
  for (const block of fontFaceBlocks) {
    assert(block.includes("format('woff2')"), `@font-face block uses format('woff2')`);
  }
}

// === 8. All declarations use font-display: swap ===
console.log('\n8. All use font-display: swap');
if (fontFaceBlocks) {
  for (const block of fontFaceBlocks) {
    assert(block.includes('font-display: swap'), '@font-face block uses font-display: swap');
  }
}

// === 9. All src URLs use relative paths to ../fonts/ ===
console.log('\n9. src URLs use relative ../fonts/ paths');
if (fontFaceBlocks) {
  for (const block of fontFaceBlocks) {
    assert(block.includes("url('../fonts/"), "@font-face src uses url('../fonts/...')");
  }
}

// === 10. download-fonts.py script exists ===
console.log('\n10. download-fonts.py script exists');
const scriptPath = join(root, 'scripts/download-fonts.py');
assert(existsSync(scriptPath), 'scripts/download-fonts.py exists');

if (existsSync(scriptPath)) {
  const script = readFileSync(scriptPath, 'utf8');
  assert(script.includes('urllib.request'), 'script uses urllib.request');
  assert(script.includes('User-Agent') || script.includes('user-agent'), 'script sets User-Agent header');
  assert(script.includes('woff2'), 'script references woff2 format');
}

// === Summary ===
console.log(`\n${'='.repeat(40)}`);
console.log(`Results: ${passed} passed, ${failed} failed out of ${passed + failed}`);
if (failed > 0) {
  process.exit(1);
} else {
  console.log('All font verification tests passed!');
}
