/**
 * SET 100b — "partially excluded" is never emitted without a behavioralSplit.
 */
import { describe, expect, it } from 'vitest';
import type { FeatureSpec, LlmClient } from '../src/core/types';
import { runTier1Job } from '../src/tier1/runner';
import { makeEvalSuiteRunner } from '../src/tier1/testExec';

const COMPUTED_PROMPT = [
  'Build a minimal wiki clone.',
  '7. Sidebar renders `<nav class="toc">` links and collapses when viewport ≤ 768px.',
].join('\n');

function pureLibSpec(): FeatureSpec {
  return {
    title: 'Wiki',
    prompt: 'wiki',
    features: [{
      id: 'F1', name: 'wiki', description: 'wiki clone', parentId: null,
      deps: [], files: ['src/wiki.ts'], testFile: 'tests/f1.test.ts',
      edgeCases: ['zero'], envVars: [],
      exports: [{ file: 'src/wiki.ts', symbol: 'render' }],
      stubs: [{
        path: 'src/wiki.ts',
        content: 'export function render(s: string): string { throw new Error("stub"); }\n',
      }],
    }],
  } as unknown as FeatureSpec;
}

class ComputedStyleLlm implements Partial<LlmClient> {
  async encodeFeatures() {
    return pureLibSpec();
  }
  async repairFeatures() { return []; }
  async fixStub() { return ''; }
  async generateTests() { return { content: '', parts: { imports: [], cases: [] } }; }
  async fixTestCases(
    _s: unknown,
    _f: unknown,
    broken: { name: string; kind: string }[],
  ) {
    return {
      cases: broken.map((b: { name: string; kind: string }) => ({
        name: b.name,
        kind: b.kind as 'behavior' | 'edge' | 'integration',
        body: 'expect(render("x")).toBe("x");',
      })),
    };
  }
  async generateImplementation() {
    return [{ path: 'src/wiki.ts', content: 'export function render(s: string): string { return s; }\n' }];
  }
  async repair() { return []; }
}

describe('SET 100b — partial label honesty', () => {
  it('never emits partially excluded for computed-style partial hits', async () => {
    const events: string[] = [];
    await runTier1Job({
      prompt: COMPUTED_PROMPT,
      rawPrompt: COMPUTED_PROMPT,
      llm: new ComputedStyleLlm() as unknown as LlmClient,
      runSuite: makeEvalSuiteRunner(),
      onEvent: e => events.push(e.message),
    });

    expect(events.some(m => m.includes('partially excluded:'))).toBe(false);
    expect(events.some(m => m.includes('excluded:') && /viewport/i.test(m))).toBe(true);
  });
});
