"""MCP Read Tools — Langfuse 데이터 조회 (7개).

모든 tool은 읽기 전용이며 governance audit을 기록합니다.
"""

import json
import logging

from fastmcp import FastMCP

from sentinel.schema import AuditEvent, ActionType, Surface

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


def _audit_read(action: str, target_refs: list[str] | None = None):
    """읽기 작업 audit 기록."""
    from sentinel.services.governance import governance

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


def register_read_tools(mcp: FastMCP):
    """읽기 전용 MCP tool 7개를 등록합니다."""

    @mcp.tool()
    def search_traces(
        name: str | None = None,
        user_id: str | None = None,
        session_id: str | None = None,
        from_timestamp: str | None = None,
        to_timestamp: str | None = None,
        limit: int = 20,
    ) -> str:
        """Langfuse 트레이스를 검색합니다.

        Args:
            name: 트레이스 이름 필터
            user_id: 사용자 ID 필터
            session_id: 세션 ID 필터
            from_timestamp: 시작 시간 (ISO format)
            to_timestamp: 종료 시간 (ISO format)
            limit: 최대 결과 수 (기본 20)

        Returns:
            JSON 형식의 트레이스 목록
        """
        from sentinel.services.registry import ServiceRegistry

        gw = ServiceRegistry.get().gateway
        traces = gw.list_traces(
            name=name,
            user_id=user_id,
            session_id=session_id,
            from_timestamp=from_timestamp,
            to_timestamp=to_timestamp,
            limit=limit,
        )
        _audit_read("mcp:search_traces")
        return json.dumps(traces, ensure_ascii=False, indent=2, default=str)

    @mcp.tool()
    def get_trace_detail(trace_id: str) -> str:
        """특정 트레이스의 상세 정보를 조회합니다.

        Args:
            trace_id: 조회할 트레이스 ID

        Returns:
            JSON 형식의 트레이스 상세 (input/output, scores, observations 포함)
        """
        from sentinel.services.registry import ServiceRegistry

        gw = ServiceRegistry.get().gateway
        detail = gw.get_trace(trace_id)
        _audit_read("mcp:get_trace_detail", [trace_id])
        return json.dumps(detail, ensure_ascii=False, indent=2, default=str)

    @mcp.tool()
    def list_sessions(limit: int = 20) -> str:
        """Langfuse 세션 목록을 조회합니다.

        Args:
            limit: 최대 결과 수 (기본 20)

        Returns:
            JSON 형식의 세션 목록
        """
        from sentinel.services.registry import ServiceRegistry

        gw = ServiceRegistry.get().gateway
        sessions = gw.list_sessions(limit=limit)
        _audit_read("mcp:list_sessions")
        return json.dumps(sessions, ensure_ascii=False, indent=2, default=str)

    @mcp.tool()
    def get_prompt_detail(name: str, label: str = "production") -> str:
        """Langfuse 프롬프트 상세를 조회합니다.

        Args:
            name: 프롬프트 이름
            label: 프롬프트 라벨 (기본 "production")

        Returns:
            JSON 형식의 프롬프트 상세 (version, prompt text 포함)
        """
        from sentinel.services.registry import ServiceRegistry

        gw = ServiceRegistry.get().gateway
        prompt = gw.get_prompt(name, label=label)
        _audit_read("mcp:get_prompt_detail", [name])
        return json.dumps(prompt, ensure_ascii=False, indent=2, default=str)

    @mcp.tool()
    def list_low_score_cases(
        threshold: float = 0.5,
        score_name: str | None = None,
        limit: int = 20,
    ) -> str:
        """낮은 점수(threshold 이하)의 평가 케이스를 조회합니다.

        Args:
            threshold: 점수 임계값 (기본 0.5)
            score_name: 특정 스코어 이름 필터
            limit: 최대 결과 수 (기본 20)

        Returns:
            JSON 형식의 낮은 점수 케이스 목록
        """
        from sentinel.services.registry import ServiceRegistry

        gw = ServiceRegistry.get().gateway
        scores = gw.list_scores(name=score_name, limit=limit * 3)
        low = [s for s in scores if (s.get("value") or 1.0) <= threshold]
        low.sort(key=lambda x: x.get("value", 0))
        result = low[:limit]
        _audit_read("mcp:list_low_score_cases")
        return json.dumps(result, ensure_ascii=False, indent=2, default=str)

    @mcp.tool()
    def get_report_summary(filename: str | None = None) -> str:
        """최근 생성된 보고서 요약을 조회합니다.

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

        Returns:
            보고서 내용 또는 목록
        """
        import os
        from sentinel.settings import REPORTS_DIR

        _audit_read("mcp:get_report_summary")

        if filename:
            path = os.path.join(REPORTS_DIR, filename)
            if os.path.exists(path):
                content = open(path, encoding="utf-8").read()
                return content[:5000]
            return json.dumps({"error": f"보고서를 찾을 수 없습니다: {filename}"})

        # 최신 보고서 목록
        if not os.path.isdir(REPORTS_DIR):
            return json.dumps({"reports": [], "message": "보고서 디렉토리가 없습니다."})

        files = sorted(os.listdir(REPORTS_DIR), reverse=True)[:10]
        return json.dumps({"reports": files}, ensure_ascii=False, indent=2)

    @mcp.tool()
    def query_audit_log(limit: int = 30, action_filter: str | None = None) -> str:
        """감사 로그를 조회합니다.

        Args:
            limit: 최대 결과 수 (기본 30)
            action_filter: 특정 액션 필터 (부분 일치)

        Returns:
            JSON 형식의 감사 로그 목록
        """
        from sentinel.audit import audit_log

        rows = audit_log.query(limit=limit)
        if action_filter:
            rows = [r for r in rows if action_filter in r.get("action", "")]

        _audit_read("mcp:query_audit_log")
        return json.dumps(rows, ensure_ascii=False, indent=2, default=str)
