"""
test_task_106_1.py - _build_glm_prompt() 수정사항 검증 테스트

태스크 106-1: glm_message 변수 내 task_desc 직접 삽입 → 파일 경로 참조 변경 검증

변경 전: f"작업 ID: {task_id}. {task_desc}. "
변경 후: f"작업 지시서: {WORKSPACE_ROOT}/memory/tasks/{task_id}.md 를 읽고 작업 수행. "
"""

import re
import sys
import os

# 프롬프트 모듈 경로 추가
sys.path.insert(0, "/home/jay/workspace")

from prompts.team_prompts import _build_glm_prompt, WORKSPACE_ROOT


# 공통 테스트 파라미터 (dev8-team: GLM 타입)
TEAM = {"name": "dev8-team", "type": "glm"}
TEAM_ID = "dev8-team"
TASK_ID = "task-106-test"
LEVEL = "normal"
TIMER_START = f"python3 {WORKSPACE_ROOT}/memory/task-timer.py start {TASK_ID} --team {TEAM_ID} --desc \"테스트\""
TIMER_END = f"python3 {WORKSPACE_ROOT}/memory/task-timer.py end {TASK_ID}"
REPORT_PATH = f"{WORKSPACE_ROOT}/memory/reports/{TASK_ID}.md"

SHORT_TASK_DESC = "A" * 50   # 50자 짧은 task_desc
LONG_TASK_DESC = "B" * 5000  # 5000자 긴 task_desc


def extract_glm_message(prompt: str) -> str:
    """
    프롬프트에서 openclaw agent 명령어 내 glm_message 부분을 추출한다.
    `openclaw agent --agent main -m "..."` 형태에서 -m "..." 의 값을 반환.
    """
    # -m "..." 패턴 추출 (따옴표 내부가 glm_message)
    match = re.search(r'-m\s+"(.*?)"(?:\s+--json|\s+--deliver|\s*$)', prompt, re.DOTALL)
    if match:
        return match.group(1)
    return ""


def test_glm_message_length_independent_of_task_desc():
    """
    요구사항 1: 짧은/긴 task_desc로 프롬프트를 생성했을 때,
    glm_message 부분의 길이가 task_desc 길이와 무관하게 일정해야 한다.
    """
    prompt_short = _build_glm_prompt(
        TEAM, TEAM_ID, TASK_ID, SHORT_TASK_DESC, LEVEL,
        TIMER_START, TIMER_END, REPORT_PATH
    )
    prompt_long = _build_glm_prompt(
        TEAM, TEAM_ID, TASK_ID, LONG_TASK_DESC, LEVEL,
        TIMER_START, TIMER_END, REPORT_PATH
    )

    glm_short = extract_glm_message(prompt_short)
    glm_long = extract_glm_message(prompt_long)

    assert glm_short != "", "짧은 task_desc로 생성 시 glm_message가 비어있음"
    assert glm_long != "", "긴 task_desc로 생성 시 glm_message가 비어있음"

    print(f"  [짧은 task_desc] glm_message 길이: {len(glm_short)}")
    print(f"  [긴  task_desc] glm_message 길이: {len(glm_long)}")

    assert len(glm_short) == len(glm_long), (
        f"glm_message 길이가 task_desc에 따라 달라짐: "
        f"짧은={len(glm_short)}, 긴={len(glm_long)}"
    )


def test_glm_message_does_not_contain_task_desc():
    """
    요구사항 2: glm_message에 task_desc 문자열이 포함되지 않아야 한다.
    """
    for desc_label, task_desc in [("짧은", SHORT_TASK_DESC), ("긴", LONG_TASK_DESC)]:
        prompt = _build_glm_prompt(
            TEAM, TEAM_ID, TASK_ID, task_desc, LEVEL,
            TIMER_START, TIMER_END, REPORT_PATH
        )
        glm_message = extract_glm_message(prompt)

        assert glm_message != "", f"{desc_label} task_desc 케이스: glm_message를 추출하지 못함"
        assert task_desc not in glm_message, (
            f"{desc_label} task_desc 케이스: glm_message에 task_desc 문자열이 포함되어 있음\n"
            f"  glm_message: {glm_message[:200]}..."
        )
        print(f"  [{desc_label} task_desc] glm_message에 task_desc 미포함 확인 OK")


def test_glm_message_contains_required_keywords():
    """
    요구사항 3: 기존 키워드(openclaw, --agent main, --json, --deliver) 보존 확인.
    """
    prompt = _build_glm_prompt(
        TEAM, TEAM_ID, TASK_ID, SHORT_TASK_DESC, LEVEL,
        TIMER_START, TIMER_END, REPORT_PATH
    )

    required_keywords = ["openclaw", "--agent main", "--json", "--deliver"]
    for keyword in required_keywords:
        assert keyword in prompt, (
            f"필수 키워드 '{keyword}'가 프롬프트에 없음"
        )
        print(f"  키워드 '{keyword}' 존재 확인 OK")


def test_prompt_body_contains_task_desc():
    """
    요구사항 4: 본문 '내용:' 필드에는 여전히 task_desc가 존재해야 한다.
    """
    for desc_label, task_desc in [("짧은", SHORT_TASK_DESC), ("긴", LONG_TASK_DESC)]:
        prompt = _build_glm_prompt(
            TEAM, TEAM_ID, TASK_ID, task_desc, LEVEL,
            TIMER_START, TIMER_END, REPORT_PATH
        )

        # "내용: {task_desc}" 패턴이 프롬프트 본문에 있는지 확인
        assert f"내용: {task_desc}" in prompt, (
            f"{desc_label} task_desc 케이스: 본문 '내용:' 필드에 task_desc가 없음"
        )
        print(f"  [{desc_label} task_desc] 본문 '내용:' 필드에 task_desc 존재 확인 OK")


def test_glm_message_contains_file_path_reference():
    """
    요구사항 5: glm_message에 파일 경로 참조(/memory/tasks/{task_id}.md)가 포함되어야 한다.
    """
    expected_path = f"/memory/tasks/{TASK_ID}.md"

    for desc_label, task_desc in [("짧은", SHORT_TASK_DESC), ("긴", LONG_TASK_DESC)]:
        prompt = _build_glm_prompt(
            TEAM, TEAM_ID, TASK_ID, task_desc, LEVEL,
            TIMER_START, TIMER_END, REPORT_PATH
        )
        glm_message = extract_glm_message(prompt)

        assert glm_message != "", f"{desc_label} task_desc 케이스: glm_message를 추출하지 못함"
        assert expected_path in glm_message, (
            f"{desc_label} task_desc 케이스: glm_message에 파일 경로 참조 '{expected_path}'가 없음\n"
            f"  glm_message: {glm_message}"
        )
        print(f"  [{desc_label} task_desc] glm_message에 경로 '{expected_path}' 포함 확인 OK")


if __name__ == "__main__":
    # pytest 없이 직접 실행 시 수동 테스트
    tests = [
        test_glm_message_length_independent_of_task_desc,
        test_glm_message_does_not_contain_task_desc,
        test_glm_message_contains_required_keywords,
        test_prompt_body_contains_task_desc,
        test_glm_message_contains_file_path_reference,
    ]
    passed = 0
    failed = 0
    for test_fn in tests:
        try:
            print(f"\n[실행] {test_fn.__name__}")
            test_fn()
            print(f"  => PASS")
            passed += 1
        except AssertionError as e:
            print(f"  => FAIL: {e}")
            failed += 1
    print(f"\n결과: {passed} passed, {failed} failed")
