#!/usr/bin/env python3
"""utils/clarify.py 테스트 스위트"""

import sys
from pathlib import Path

import pytest

sys.path.insert(0, str(Path(__file__).parent.parent.parent))

from utils.clarify import AmbiguityReport, analyze_ambiguity


class TestAmbiguityReport:
    """AmbiguityReport dataclass 구조 테스트"""

    def test_dataclass_has_required_fields(self):
        """score, missing_dimensions, suggested_questions 필드 존재"""
        report = AmbiguityReport(
            score=5,
            missing_dimensions=["What", "Why"],
            suggested_questions=["무엇을 원하시나요?"],
        )
        assert report.score == 5
        assert report.missing_dimensions == ["What", "Why"]
        assert report.suggested_questions == ["무엇을 원하시나요?"]

    def test_score_type_is_int_or_float(self):
        """score는 숫자형"""
        report = analyze_ambiguity("뭔가 해줘")
        assert isinstance(report.score, (int, float))

    def test_missing_dimensions_is_list(self):
        """missing_dimensions는 리스트"""
        report = analyze_ambiguity("뭔가 해줘")
        assert isinstance(report.missing_dimensions, list)

    def test_suggested_questions_is_list(self):
        """suggested_questions는 리스트"""
        report = analyze_ambiguity("뭔가 해줘")
        assert isinstance(report.suggested_questions, list)


class TestAnalyzeAmbiguity:
    """analyze_ambiguity() 핵심 동작 테스트"""

    def test_returns_ambiguity_report(self):
        """반환 타입은 AmbiguityReport"""
        result = analyze_ambiguity("뭔가 해줘")
        assert isinstance(result, AmbiguityReport)

    def test_empty_request_high_score(self):
        """빈 요청은 높은 모호성 점수"""
        report = analyze_ambiguity("")
        assert report.score >= 8

    def test_empty_request_all_dimensions_missing(self):
        """빈 요청은 모든 5W1H 차원 누락"""
        report = analyze_ambiguity("")
        assert len(report.missing_dimensions) == 6  # What/Why/Where/When/Who/How

    def test_vague_request_high_score(self):
        """모호한 요청은 높은 점수"""
        report = analyze_ambiguity("뭔가 만들어줘")
        assert report.score >= 5

    def test_detailed_request_low_score(self):
        """상세한 요청은 낮은 모호성 점수"""
        detailed = (
            "파이썬으로 CSV 파일을 읽어서 데이터를 분석하는 스크립트를 "
            "이번 주 금요일까지 작성해줘. 팀장님 보고용으로 평균과 합계를 "
            "계산하는 방식으로 구현해줘."
        )
        report = analyze_ambiguity(detailed)
        assert report.score < 5

    def test_score_range_0_to_10(self):
        """score는 0~10 범위"""
        for req in ["", "뭔가 해줘", "상세하고 구체적인 요청입니다"]:
            report = analyze_ambiguity(req)
            assert 0 <= report.score <= 10

    def test_suggested_questions_not_empty_when_ambiguous(self):
        """모호한 요청에는 제안 질문 포함"""
        report = analyze_ambiguity("뭔가 해줘")
        assert len(report.suggested_questions) > 0

    def test_what_dimension_detected_missing(self):
        """범위/대상(What) 정보 없으면 missing_dimensions에 포함"""
        report = analyze_ambiguity("언제까지 해줘")
        assert "What" in report.missing_dimensions

    def test_when_dimension_detected_present(self):
        """일정(When) 정보 있으면 missing_dimensions에 미포함"""
        report = analyze_ambiguity("이번 주 금요일까지 완료해줘")
        assert "When" not in report.missing_dimensions

    def test_why_dimension_detected_present(self):
        """목적(Why) 정보 있으면 missing_dimensions에 미포함"""
        report = analyze_ambiguity("성능 향상을 위해 코드를 최적화해줘")
        assert "Why" not in report.missing_dimensions

    def test_who_dimension_detected_present(self):
        """이해관계자(Who) 정보 있으면 누락 아님"""
        report = analyze_ambiguity("개발팀이 사용할 도구를 만들어줘")
        assert "Who" not in report.missing_dimensions

    def test_how_dimension_detected_present(self):
        """방법(How) 정보 있으면 누락 아님"""
        report = analyze_ambiguity("REST API 방식으로 구현해줘")
        assert "How" not in report.missing_dimensions

    def test_suggested_questions_cover_missing_dimensions(self):
        """missing_dimensions 각 항목에 대응하는 질문 생성"""
        report = analyze_ambiguity("")
        # 각 누락된 차원마다 최소 1개 질문
        assert len(report.suggested_questions) >= len(report.missing_dimensions)

    def test_no_duplicate_missing_dimensions(self):
        """missing_dimensions에 중복 없음"""
        report = analyze_ambiguity("뭔가 해줘")
        assert len(report.missing_dimensions) == len(set(report.missing_dimensions))


class TestDimensions5W1H:
    """5W1H 각 차원별 키워드 감지 테스트"""

    def test_what_keywords_reduce_score(self):
        """What 키워드(구현, 작성, 분석 등)가 있으면 What 차원 충족"""
        report = analyze_ambiguity("파이썬 스크립트를 작성해줘")
        assert "What" not in report.missing_dimensions

    def test_where_keywords_reduce_score(self):
        """Where 키워드(서버, DB, 파일 등)가 있으면 Where 차원 충족"""
        report = analyze_ambiguity("데이터베이스에 저장해줘")
        assert "Where" not in report.missing_dimensions

    def test_all_dimensions_present_gives_low_score(self):
        """6개 차원 모두 충족 시 score 0"""
        full_request = (
            "백엔드 개발팀이 사용할 REST API를 "
            "성능 향상을 위해 파이썬으로 구현해줘. "
            "이번 달 말까지 서버에 배포 완료해야 해."
        )
        report = analyze_ambiguity(full_request)
        assert report.score == 0
        assert report.missing_dimensions == []
