/**
 * 단계별 지식 스코프 라우터 — 도메인 분류(휴리스틱)와 폴더 조합 규칙 검증.
 * 소형 모델 정밀 검색의 핵심 계약: 확신 없으면 'general'(전체 두뇌)로 보수적 폴백.
 */
import { classifyKnowledgeDomain, combineDomainFolders, buildDomainRoutingHint } from '../src/retrieval/domainRouter';

jest.mock('vscode', () => ({ workspace: { getConfiguration: jest.fn() } }), { virtual: true });

describe('classifyKnowledgeDomain', () => {
    it('코드 펜스가 있으면 coding 확정', () => {
        expect(classifyKnowledgeDomain('이 코드 왜 안 돼?\n```js\nconsole.log(x)\n```')).toBe('coding');
    });

    it('코딩 신호: 에러/파일 확장자/언어명', () => {
        expect(classifyKnowledgeDomain('TypeError: cannot read properties of undefined 에러가 나요')).toBe('coding');
        expect(classifyKnowledgeDomain('sidebarProvider.ts 파일의 함수를 리팩토링해줘')).toBe('coding');
        expect(classifyKnowledgeDomain('python으로 API endpoint 구현해줘')).toBe('coding');
    });

    it('수학 신호: 연산식/백분율/수학 용어', () => {
        expect(classifyKnowledgeDomain('1234 * 5678 계산해줘')).toBe('math');
        expect(classifyKnowledgeDomain('원금 500만원에 연 3.5% 복리 이자면 10년 뒤 얼마야?')).toBe('math');
        expect(classifyKnowledgeDomain('주사위 두 개 던져서 합이 7일 확률은?')).toBe('math');
    });

    it('팩트 신호: 질문사/정의 요청 (다른 도메인 신호가 없을 때만)', () => {
        expect(classifyKnowledgeDomain('세종대왕이 누구야?')).toBe('facts');
        expect(classifyKnowledgeDomain('OLED와 QLED의 차이가 뭐야?')).toBe('facts');
    });

    it('신호가 없거나 애매하면 general (전체 두뇌 폴백)', () => {
        expect(classifyKnowledgeDomain('오늘 하루 어땠어?')).toBe('general');
        expect(classifyKnowledgeDomain('')).toBe('general');
        expect(classifyKnowledgeDomain('고마워!')).toBe('general');
    });

    it('코딩+팩트 혼합 신호는 전문 도메인(coding)이 이긴다', () => {
        expect(classifyKnowledgeDomain('git rebase가 뭐야? 설명해줘')).toBe('coding');
    });
});

describe('combineDomainFolders — General+Specialty 조합 규칙', () => {
    const cfg = { general: 'General', math: 'Specialty_Math', coding: '10_Wiki/Topic_Programming', facts: '' };

    it('도메인 분류 성공 + Specialty 설정됨 → [General, Specialty]', () => {
        expect(combineDomainFolders('coding', cfg)).toEqual(['General', '10_Wiki/Topic_Programming']);
        expect(combineDomainFolders('math', cfg)).toEqual(['General', 'Specialty_Math']);
    });

    it('Specialty 미설정 도메인은 스코프 미적용 (General만으로 좁히지 않음)', () => {
        expect(combineDomainFolders('facts', cfg)).toEqual([]);
    });

    it('general 도메인은 항상 스코프 미적용 (레거시 전체 검색)', () => {
        expect(combineDomainFolders('general', cfg)).toEqual([]);
    });

    it('General 미설정이면 Specialty 단독으로 스코프', () => {
        expect(combineDomainFolders('math', { ...cfg, general: '' })).toEqual(['Specialty_Math']);
    });
});

describe('buildDomainRoutingHint — 분류 1회로 도구 유도까지', () => {
    it('math → calculate 위임 지시', () => {
        expect(buildDomainRoutingHint('math')).toContain('<calculate>');
        expect(buildDomainRoutingHint('math')).toContain('암산');
    });
    it('coding → run_code 실행 확인 + edit_file 수정 루프 지시', () => {
        const hint = buildDomainRoutingHint('coding');
        expect(hint).toContain('<run_code');
        expect(hint).toContain('<edit_file>');
    });
    it('facts → 근거 없으면 확인 불가 / fetch_url', () => {
        const hint = buildDomainRoutingHint('facts');
        expect(hint).toContain('확인 불가');
        expect(hint).toContain('<fetch_url>');
    });
    it('general → 힌트 없음 (기존 동작 무간섭)', () => {
        expect(buildDomainRoutingHint('general')).toBe('');
    });
});
