import { describe, test, afterEach } from 'node:test';
import assert from 'node:assert/strict';
import { execFileSync } from 'node:child_process';
import { mkdtempSync, rmSync, mkdirSync, writeFileSync, existsSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { tmpdir } from 'node:os';
import { fileURLToPath } from 'node:url';

// M0-8 / SC7: the UserPromptSubmit hook must point the voice-profile hint at the
// REAL artefact in the EXTERNAL data root (getDataRoot('voice-samples')), not the
// in-plugin placeholder. This hook is a procedural stdin->stdout CLI with no
// exports, so we test it end-to-end as a subprocess: pipe the prompt JSON, stub
// LINKEDIN_STUDIO_DATA + STATE_FILE, and inspect the injected systemMessage.
const hookPath = join(dirname(fileURLToPath(import.meta.url)), '..', 'user-prompt-context.mjs');

function runHook(prompt, env) {
  const out = execFileSync('node', [hookPath], {
    input: JSON.stringify({ prompt }),
    env: { ...process.env, ...env },
    encoding: 'utf-8',
  });
  return JSON.parse(out);
}

describe('user-prompt-context — voice hint points at external data root (M0-8/SC7)', () => {
  let dataDir;

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

  test('real external voice present → systemMessage references the external voice file', () => {
    dataDir = mkdtempSync(join(tmpdir(), 'lis-upc-'));
    mkdirSync(join(dataDir, 'voice-samples'), { recursive: true });
    writeFileSync(join(dataDir, 'voice-samples', 'authentic-voice-samples.md'), '# My Voice\n\nreal content\n', 'utf-8');

    const result = runHook('write a linkedin post', {
      LINKEDIN_STUDIO_DATA: dataDir,
      STATE_FILE: join(dataDir, 'no-state.local.md'),
    });

    assert.ok(result.systemMessage, 'a LinkedIn prompt must produce an enrichment systemMessage');
    assert.ok(
      result.systemMessage.includes(join(dataDir, 'voice-samples', 'authentic-voice-samples.md')),
      'voice hint must point at the external voice file, not the in-plugin placeholder',
    );
  });

  test('external voice absent → no voice-profile hint injected (graceful degradation)', () => {
    dataDir = mkdtempSync(join(tmpdir(), 'lis-upc-'));
    // no voice-samples dir/file seeded under the external root

    const result = runHook('write a linkedin post', {
      LINKEDIN_STUDIO_DATA: dataDir,
      STATE_FILE: join(dataDir, 'no-state.local.md'),
    });

    assert.ok(result.systemMessage, 'still enriches (scorecard reminder), just without the voice hint');
    assert.ok(
      !result.systemMessage.includes('Voice Profile:'),
      'no voice hint when the external voice artefact is absent',
    );
  });
});
