/**
 * SET 42g — fifth tone FRICTION + operational yellow pins (42f discipline).
 * SET 45a — orthogonal substrate flag for (0 tok) events.
 */
import { describe, expect, it } from 'vitest';
import {
  EVENT_KIND_TONES,
  classifyEventKind,
  eventFlags,
  eventTone,
  isSubstrateEvent,
  toneForKind,
  toneToCss,
} from '../src/tier1/eventTone';

describe('SET 42g friction tone', () => {
  it('registers friction kinds and maps to CSS friction', () => {
    expect(EVENT_KIND_TONES['rejected-draw']).toBe('friction');
    expect(EVENT_KIND_TONES['incumbent-kept']).toBe('friction');
    expect(EVENT_KIND_TONES['skip-no-track']).toBe('friction');
    expect(EVENT_KIND_TONES['partial-passing']).toBe('friction');
    expect(EVENT_KIND_TONES['program-parse-rejection']).toBe('friction');
    expect(EVENT_KIND_TONES['vet-rejection']).toBe('friction');
    expect(toneToCss('friction')).toBe('friction');
    expect(toneForKind('rejected-draw')).toBe('friction');
  });

  it('PINNED — rejected draws / parse / vet → friction (not red)', () => {
    const pinned = [
      { message: 'build draw rejected: syntax error', expect: 'friction' },
      { message: 'repair draw rejected: empty', expect: 'friction' },
      { message: 'reset draw rejected: no parse', expect: 'friction' },
      { message: 'program-parse rejection — incumbent kept', expect: 'friction' },
      { message: 'artifact vet rejected: boundary', expect: 'friction' },
      { message: 'pass 2: no improvement — incumbent kept', expect: 'friction' },
      { message: 'retry skipped: no new track to lay', expect: 'friction' },
      { message: '3/5 passing', expect: 'friction' },
    ] as const;
    for (const p of pinned) {
      expect(eventTone({ message: p.message, phase: 'rha' }), p.message).toBe(p.expect);
    }
    // Full fail stays red-adjacent; full pass stays green.
    expect(eventTone({ message: '0/5 passing', phase: 'auth' })).toBe('red');
    expect(eventTone({ message: '5/5 passing', phase: 'auth' })).toBe('green');
  });

  it('PINNED NEGATIVE — operational machinery stays yellow (never green)', () => {
    const yellow = [
      'superbuffer: assembled (2 stubs, 1 frozen, 0 templates, 0 lessons, 0 siblings; pages [spec:10]) stage=fill for "x"',
      'fill batch: targets [a, b]',
      'plan: 3 cases (1 substrate-templated, 2 model draws)',
      'repair pass 1: 2/4 findings [assertion|eq] + superbuffer, permutation K=3',
      'concept draw: F1 (120 chars, context only)',
    ];
    for (const message of yellow) {
      expect(eventTone({ message, phase: 'ir' }), message).toBe('yellow');
      expect(eventTone({ message, phase: 'ir' })).not.toBe('green');
    }
  });

  it('terminal failures stay red', () => {
    expect(eventTone({ message: 'case "x" dropped — unparseable: Unexpected token' })).toBe('red');
    expect(eventTone({ message: 'no-coverage — abandoned after metaloop 3' })).toBe('red');
    expect(eventTone({ message: 'blocked-crash: parked (crash|unattributed)' })).toBe('red');
  });
});

describe('SET 45a substrate flag', () => {
  it('every (0 tok) fixture carries substrate:true', () => {
    const zeroTok = [
      'case "x" healed via delimiter (0 tok)',
      'case "x" rebound via clade (0 tok)',
      'substrate: assertion|eq → refused(ambiguous) (0 tok)',
      'substrate: assertion|eq → no-handler (0 tok)',
      'partially excluded: viewport ≤ 768px (line 12) — computed-style (0 tok)',
      'repair skipped: mock-api is mechanical-only (0 model draws)',
    ];
    for (const message of zeroTok) {
      if (/\(0 tok\)/.test(message)) {
        expect(isSubstrateEvent({ message, phase: 'rha' }), message).toBe(true);
        expect(eventFlags({ message }).substrate).toBe(true);
      }
    }
    expect(isSubstrateEvent({ message: 'born-red check: suite has failing case' })).toBe(true);
    expect(isSubstrateEvent({ message: 'program-parse rejection — incumbent kept' })).toBe(true);
    expect(isSubstrateEvent({ message: 'LLM fixTestCases · F1: 100 in / 40 out' })).toBe(false);
  });

  it('substrate flag is orthogonal to tone (green heal still substrate)', () => {
    const msg = 'case "x" healed via delimiter (0 tok)';
    expect(eventTone({ message: msg })).toBe('green');
    expect(isSubstrateEvent({ message: msg })).toBe(true);
    expect(classifyEventKind({ message: msg })).toBe('healed');
  });
});
