/**
 * Terminology Dictionary — 프로젝트 표준 용어집을 시스템 프롬프트에 주입.
 *
 * 사용자 제안: "표준 표기 강제 + 답변 내 표기 일관성 검증". 예: `runway` vs `런웨이`,
 * `P-Reinforce` vs `p-reinforce`, `Chronicle` vs `크로니클`.
 *
 * 설계 — 사용자 편집 markdown 파일:
 *   - 위치: `<workspace>/.astra/glossary.md`
 *   - 형식: 자유 markdown. ASTRA 는 *형식을 강제하지 않고* 통째로 주입
 *   - 권장 컨벤션: H2/H3 섹션으로 표준 표기 / 영-한 컨벤션 / 금지 용어 등 그룹핑
 *
 * 시스템 프롬프트 블록 `[TERMINOLOGY DICTIONARY]`:
 *   - 글로서리 본문 + Term Check 지침 (#1 typo/용어 self-check 사용자 제안 통합)
 *   - 답변 작성 시 표준 표기 우선 + 답변 직전 자기 점검 + 새 용어 도입 시 명시
 *
 * 캐시: 파일 mtime 기반 — 매 turn 디스크 read 안 함.
 */

import * as path from 'path';
import * as vscode from 'vscode';
import { createMtimeFileCache } from '../lib/mtimeFileCache';

const DEFAULT_GLOSSARY_REL_PATH = '.astra/glossary.md';

/** Raw 본문 캐시 — mtime 기반, 파일 편집 시 자동 재read. */
const _rawCache = createMtimeFileCache<string>('terminology-raw', (raw) => raw.trim());

export function getGlossaryFilePath(relPath: string = DEFAULT_GLOSSARY_REL_PATH): string | null {
    const folders = vscode.workspace.workspaceFolders;
    if (!folders || folders.length === 0) return null;
    return path.join(folders[0].uri.fsPath, relPath);
}

function readGlossary(relPath: string): string {
    const fp = getGlossaryFilePath(relPath);
    if (!fp) return '';
    return _rawCache.read(fp) ?? '';
}

export function clearGlossaryCache(): void {
    _rawCache.clear();
}

export interface TerminologyBlockOptions {
    /** Glossary 파일 상대 경로. 기본 '.astra/glossary.md'. */
    relPath: string;
    /** 본문 최대 길이 (chars). 너무 큰 글로서리는 시스템 프롬프트 비대 — cap. 기본 4000. */
    maxBodyLength: number;
    /** 길이 초과 시 잘릴 안내 표시 여부. */
    showTruncationNote: boolean;
}

export const DEFAULT_TERMINOLOGY_OPTIONS: TerminologyBlockOptions = {
    relPath: DEFAULT_GLOSSARY_REL_PATH,
    maxBodyLength: 4000,
    showTruncationNote: true,
};

export function buildTerminologyBlock(options: Partial<TerminologyBlockOptions> = {}): string {
    const opts: TerminologyBlockOptions = { ...DEFAULT_TERMINOLOGY_OPTIONS, ...options };
    const raw = readGlossary(opts.relPath);
    if (!raw) return ''; // 파일 없음 → 블록 안 만듦 (no-op)

    let body = raw;
    let truncated = false;
    if (body.length > opts.maxBodyLength) {
        body = body.slice(0, opts.maxBodyLength);
        truncated = true;
    }

    const lines: string[] = [];
    lines.push('[TERMINOLOGY DICTIONARY]');
    lines.push('프로젝트 표준 용어집. 답변 생성 시 다음 표기·컨벤션을 *최우선* 으로 사용.');
    lines.push('');
    lines.push('---');
    lines.push(body);
    if (truncated && opts.showTruncationNote) {
        lines.push('');
        lines.push(`_…(글로서리 ${raw.length - opts.maxBodyLength}자 잘림 — 핵심 용어를 앞쪽에 배치해 주세요)_`);
    }
    lines.push('---');

    // Term Check 지침 — 사용자 제안 #1 (typo/용어 self-check) 통합.
    lines.push('');
    lines.push('[Term Check — 답변 직전 자기 점검]');
    lines.push('1. **표준 표기 우선**: 위 용어가 답변에 등장하면 *글로서리의 표기를 그대로* 사용. 변형·번역 임의 적용 금지.');
    lines.push('2. **표기 흔들림 방지**: 같은 용어를 한 답변 안에서 *동일 표기* 로 일관 사용 (예: "Chronicle" 과 "크로니클" 섞지 말 것).');
    lines.push('3. **새 용어 도입 시**: 글로서리에 없는 고유 명사·약어 처음 사용 시 *"새 용어: X"* 라고 한 번 명시.');
    lines.push('4. **금지 표기 검증**: 답변 직전, 글로서리의 *금지·비추* 항목이 답변에 들어가지 않았는지 검토. 들어갔으면 *재작성*.');
    lines.push('5. **모르겠으면 글로서리**: 표기 확신 없을 때 "글로서리에 없어 일반 표기 사용" 한 줄 명시 후 진행.');
    lines.push('[/TERMINOLOGY DICTIONARY]');

    return lines.join('\n');
}

/**
 * 글로서리 파일 작성 도우미 — 처음 사용자가 만들 때 권장 컨벤션 템플릿.
 * 슬래시 명령 `/glossary init` 등에서 호출.
 */
export const GLOSSARY_TEMPLATE = `# 프로젝트 용어집

ASTRA 가 답변 시 표준 표기로 사용. 사용자가 자유롭게 편집 가능.
파일 저장 후 다음 채팅 turn 부터 자동 반영.

## 표준 표기

- **ASTRA** (X: astra, Astra 외) — 본 VS Code extension 이름
- **P-Reinforce v3.0** (X: p-reinforce, p reinforce) — 지식 압축 규칙
- **Chronicle ADR** (X: chronicle, ADR 단독) — 의사결정 기록

## 영-한 표기 컨벤션

- Performance → 성능
- Bug → 버그
- Memory → 메모리

## 금지·비추 표현

- ❌ "절대적", "반드시" (단정적 표현 — 정책 충돌 위험)
- ❌ "에이전트가 알아서" (그라운딩 위반)
- ❌ 한·영 깨짐 (예: "결ently", "p-rein동")

## 슬래시 명령 표기

원문 그대로 — 한국어 번역 금지:
- /runway, /customers, /hire, /morning, /evening, /weekly, /cohort, /memory, /glossary
`;
