/**
 * Wave 5 Step 14 — Group B command-template shape tests.
 *
 * Verifies that the 6 audit/analysis command templates in Group B have the
 * correct structural shape after the humanizer integration:
 *
 *   - All 6 files: contain a Bash invocation block, reference the Read tool,
 *     and contain the `--raw` flag (or the literal `"$ARGUMENTS"` string).
 *
 *   - Findings-rendering files (drift.md, plugin-health.md, config-audit.md,
 *     discover.md, analyze.md): reference at least one of
 *     `userImpactCategory|userActionLanguage|relevanceContext`, and do NOT
 *     contain hardcoded grade-prose tables of the form `[ABCDF]\s+grade\s+is`.
 *
 *   - status.md: phase-label table is present, the machine field name
 *     `current_phase` is preserved (machine contract), and at least one
 *     humanized phase label appears ("Looking at your config files",
 *     "Working out what to recommend", "Putting together your action plan",
 *     "Making the changes", "Double-checking everything worked").
 *
 *   - Anchor must-contains from plan line 575–579:
 *     - config-audit.md: contains userImpactCategory|userActionLanguage
 *     - drift.md: contains --raw OR humanized
 */

import { test } from 'node:test';
import { strict as assert } from 'node:assert';
import { readFile } from 'node:fs/promises';
import { resolve, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const COMMANDS_DIR = resolve(__dirname, '..', '..', 'commands');

const GROUP_B_FILES = [
  'drift.md',
  'plugin-health.md',
  'config-audit.md',
  'discover.md',
  'analyze.md',
  'status.md',
];

const FINDINGS_RENDERING_FILES = [
  'drift.md',
  'plugin-health.md',
  'config-audit.md',
  'discover.md',
  'analyze.md',
];

const HUMANIZED_FIELD_REGEX = /userImpactCategory|userActionLanguage|relevanceContext/;
const RAW_OR_ARGUMENTS_REGEX = /--raw|"\$ARGUMENTS"/;
const HARDCODED_GRADE_PROSE_REGEX = /[ABCDF]\s+grade\s+is/;
const BASH_BLOCK_REGEX = /```bash\b/;
const READ_TOOL_REGEX = /\bRead\s+tool\b|allowed-tools:.*\bRead\b/;

const HUMANIZED_PHASE_LABELS = [
  'Looking at your config files',
  'Working out what to recommend',
  'Asking what you',
  'Putting together your action plan',
  'Making the changes',
  'Double-checking everything worked',
];

async function readCommand(name) {
  return await readFile(resolve(COMMANDS_DIR, name), 'utf-8');
}

test('Group B: every file contains a Bash invocation block', async () => {
  for (const name of GROUP_B_FILES) {
    const content = await readCommand(name);
    assert.match(content, BASH_BLOCK_REGEX, `${name} missing bash block`);
  }
});

test('Group B: every file references the Read tool', async () => {
  for (const name of GROUP_B_FILES) {
    const content = await readCommand(name);
    assert.match(content, READ_TOOL_REGEX, `${name} missing Read tool reference`);
  }
});

test('Group B: every file contains --raw or "$ARGUMENTS" (pass-through plumbing)', async () => {
  for (const name of GROUP_B_FILES) {
    const content = await readCommand(name);
    assert.match(content, RAW_OR_ARGUMENTS_REGEX, `${name} missing --raw / $ARGUMENTS plumbing`);
  }
});

test('Group B findings-renderers: reference at least one humanized field', async () => {
  for (const name of FINDINGS_RENDERING_FILES) {
    const content = await readCommand(name);
    assert.match(
      content,
      HUMANIZED_FIELD_REGEX,
      `${name} must reference userImpactCategory, userActionLanguage, or relevanceContext`,
    );
  }
});

test('Group B findings-renderers: no hardcoded grade-prose tables', async () => {
  for (const name of FINDINGS_RENDERING_FILES) {
    const content = await readCommand(name);
    assert.doesNotMatch(
      content,
      HARDCODED_GRADE_PROSE_REGEX,
      `${name} contains a hardcoded "[grade] grade is..." prose table — humanizer owns grade vocabulary now`,
    );
  }
});

test('Group B anchor: config-audit.md references userImpactCategory|userActionLanguage', async () => {
  const content = await readCommand('config-audit.md');
  assert.match(content, /userImpactCategory|userActionLanguage/);
});

test('Group B anchor: drift.md references --raw or humanized', async () => {
  const content = await readCommand('drift.md');
  assert.match(content, /--raw|humanized/);
});

test('status.md: preserves current_phase machine field and adds humanized phase labels', async () => {
  const content = await readCommand('status.md');
  // Machine contract preserved
  assert.match(content, /\bcurrent_phase\b/, 'status.md must keep current_phase as machine field');
  // At least 3 of the 6 humanized phase labels appear
  const present = HUMANIZED_PHASE_LABELS.filter(label => content.includes(label));
  assert.ok(
    present.length >= 3,
    `status.md must include at least 3 humanized phase labels; found ${present.length}: ${present.join(', ')}`,
  );
});
