import { describe, test, afterEach } from 'node:test';
import assert from 'node:assert/strict';
import { mkdtempSync, rmSync, mkdirSync, writeFileSync, existsSync } from 'node:fs';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
import { calculateScore } from '../personalization-score.mjs';

// Step 5 (remediation): the shipped voice profile is a PII-free placeholder
// carrying the sentinel below. Detection must key on the sentinel — NOT the old
// `[Your Name]` heuristic — so the placeholder earns 0 of the 25 voice points,
// and a populated profile (sentinel removed) earns them.
const SENTINEL = '<!-- VOICE_PLACEHOLDER -->';

// A >50-line body that contains NEITHER the sentinel NOR `[Your Name]`, so the
// only thing distinguishing placeholder from real profile is the sentinel.
const LONG_BODY = Array.from({ length: 60 }, (_, i) => `- voice characteristic line ${i + 1}`).join('\n');

function makePluginRoot() {
  const root = mkdtempSync(join(tmpdir(), 'lis-personalization-'));
  mkdirSync(join(root, 'assets', 'voice-samples'), { recursive: true });
  return root;
}

function writeVoice(root, content) {
  writeFileSync(join(root, 'assets', 'voice-samples', 'authentic-voice-samples.md'), content, 'utf-8');
}

describe('calculateScore — voice samples (sentinel-based placeholder detection)', () => {
  let root;

  afterEach(() => {
    if (root && existsSync(root)) {
      rmSync(root, { recursive: true, force: true });
    }
    root = undefined;
  });

  test('placeholder with the sentinel scores 0 voice points (even >50 lines, no [Your Name])', () => {
    root = makePluginRoot();
    writeVoice(root, `# Voice Profile (placeholder)\n${SENTINEL}\n\n${LONG_BODY}\n`);

    const { score, personalized } = calculateScore(root);

    assert.equal(score, 0, 'placeholder must not earn the 25 voice points');
    assert.equal(personalized, 0);
  });

  test('a real profile (no sentinel, >50 lines) earns the 25 voice points', () => {
    root = makePluginRoot();
    writeVoice(root, `# My Voice Profile\n\n${LONG_BODY}\n`);

    const { score, personalized } = calculateScore(root);

    assert.equal(score, 25, 'a populated profile must earn the 25 voice points');
    assert.equal(personalized, 1);
  });

  test('a short placeholder (<50 lines) also scores 0 voice points', () => {
    root = makePluginRoot();
    writeVoice(root, `# Voice Profile (placeholder)\n${SENTINEL}\n`);

    const { score } = calculateScore(root);

    assert.equal(score, 0);
  });
});
