"""MCP Analyze Tools — Trace 분석/요약 (4개).

분석 전용 tool — 상태 변경 없음, governance audit 기록.
"""

import json
import logging

from fastmcp import FastMCP

from sentinel.schema import AuditEvent, ActionType, Surface

logger = logging.getLogger("sentinel.mcp.analyze")


def _audit_analyze(action: str, target_refs: list[str] | None = None):
    from sentinel.services.governance import governance

    governance.record_action(AuditEvent(
        action=action,
        action_type=ActionType.ANALYZE,
        actor="mcp_client",
        surface=Surface.MCP,
        target_refs=target_refs or [],
        is_mutation=False,
    ))


def register_analyze_tools(mcp: FastMCP):
    """분석 MCP tool 4개를 등록합니다."""

    @mcp.tool()
    def find_similar_traces(seed_trace_id: str, limit: int = 10) -> str:
        """seed trace와 유사한 trace들을 검색합니다.

        name/tags/level 기반 heuristic으로 유사도를 판단합니다.

        Args:
            seed_trace_id: 기준이 되는 trace ID
            limit: 최대 결과 수 (기본 10)

        Returns:
            JSON 형식의 유사 trace 목록 (similarity score 포함)
        """
        from sentinel.services.registry import ServiceRegistry

        svc = ServiceRegistry.get().trace_analysis
        result = svc.find_similar_traces(seed_trace_id, limit=limit)
        _audit_analyze("mcp:find_similar_traces", [seed_trace_id])
        return json.dumps(result, ensure_ascii=False, indent=2, default=str)

    @mcp.tool()
    def summarize_trace_cluster(trace_ids: list[str]) -> str:
        """여러 trace의 failure 패턴을 분석하고 클러스터를 요약합니다.

        Args:
            trace_ids: 분석할 trace ID 목록

        Returns:
            JSON 형식의 클러스터 요약 (failure patterns, common traits, severity)
        """
        from sentinel.services.registry import ServiceRegistry

        svc = ServiceRegistry.get().trace_analysis
        result = svc.summarize_cluster(trace_ids)
        _audit_analyze("mcp:summarize_trace_cluster", trace_ids)
        return json.dumps(result, ensure_ascii=False, indent=2, default=str)

    @mcp.tool()
    def summarize_prompt_risk(prompt_name: str) -> str:
        """프롬프트의 리스크 요소를 분석합니다.

        관련 trace의 낮은 점수, 에러 패턴을 기반으로 리스크를 평가합니다.

        Args:
            prompt_name: 분석할 프롬프트 이름

        Returns:
            JSON 형식의 리스크 분석 결과
        """
        from sentinel.services.registry import ServiceRegistry

        gw = ServiceRegistry.get().gateway

        # 프롬프트 정보
        try:
            prompt_detail = gw.get_prompt(prompt_name)
        except Exception:
            return json.dumps({"error": f"프롬프트를 찾을 수 없습니다: {prompt_name}"})

        # 관련 trace에서 낮은 점수 검색
        scores = gw.list_scores(limit=50)
        low_scores = [s for s in scores if (s.get("value") or 1.0) <= 0.5]

        # 해당 prompt 이름의 trace 검색
        traces = gw.list_traces(name=prompt_name, limit=20)

        result = {
            "prompt_name": prompt_name,
            "prompt_version": prompt_detail.get("version"),
            "prompt_length": len(prompt_detail.get("prompt", "")),
            "related_trace_count": len(traces),
            "low_score_count": len(low_scores),
            "risk_level": "high" if len(low_scores) > 5 else "medium" if low_scores else "low",
            "risk_factors": [],
        }

        if len(prompt_detail.get("prompt", "")) > 3000:
            result["risk_factors"].append("프롬프트가 3000자 이상으로 과도하게 길 수 있음")
        if low_scores:
            result["risk_factors"].append(
                f"관련 낮은 점수 {len(low_scores)}건 발견"
            )
        if not traces:
            result["risk_factors"].append("관련 trace가 없어 사용 현황 파악 불가")

        _audit_analyze("mcp:summarize_prompt_risk", [prompt_name])
        return json.dumps(result, ensure_ascii=False, indent=2, default=str)

    @mcp.tool()
    def summarize_report_actions(filename: str | None = None) -> str:
        """보고서에서 권장 조치 사항을 추출합니다.

        Args:
            filename: 보고서 파일명 (없으면 최신 보고서)

        Returns:
            JSON 형식의 권장 조치 목록
        """
        import os
        import re
        from sentinel.settings import REPORTS_DIR

        if not filename:
            if os.path.isdir(REPORTS_DIR):
                files = sorted(os.listdir(REPORTS_DIR), reverse=True)
                md_files = [f for f in files if f.endswith(".md")]
                if md_files:
                    filename = md_files[0]

        if not filename:
            return json.dumps({"error": "보고서를 찾을 수 없습니다."})

        path = os.path.join(REPORTS_DIR, filename)
        if not os.path.exists(path):
            return json.dumps({"error": f"파일 없음: {filename}"})

        content = open(path, encoding="utf-8").read()

        # "권장 조치" 섹션 추출
        actions = []
        in_actions = False
        for line in content.split("\n"):
            if "권장 조치" in line or "Recommended" in line.lower():
                in_actions = True
                continue
            if in_actions:
                if line.startswith("## ") or line.startswith("---"):
                    break
                stripped = line.strip()
                if stripped.startswith("- ") or stripped.startswith("* "):
                    actions.append(stripped[2:].strip())

        # 우선순위 분류
        categorized = {"urgent": [], "important": [], "improvement": [], "other": []}
        for a in actions:
            lower = a.lower()
            if "긴급" in a or "critical" in lower:
                categorized["urgent"].append(a)
            elif "중요" in a or "important" in lower:
                categorized["important"].append(a)
            elif "개선" in a or "improve" in lower:
                categorized["improvement"].append(a)
            else:
                categorized["other"].append(a)

        result = {
            "filename": filename,
            "total_actions": len(actions),
            "actions": categorized,
        }

        _audit_analyze("mcp:summarize_report_actions", [filename])
        return json.dumps(result, ensure_ascii=False, indent=2, default=str)
