#!/usr/bin/env python3
"""
scripts/session_watchdog.py — 봇 세션 건강 상태 모니터링 워치독

전체 봇 세션의 토큰 사용량을 체크하고, 임계값 도달 시 자동 대응.
cron으로 주기적 실행하거나, 수동으로 1회 실행 가능.

Usage:
    python3 scripts/session_watchdog.py --check     # 1회 체크 + 자동 대응
    python3 scripts/session_watchdog.py --status    # 현재 상태만 출력 (대응 없음)

Exit Codes:
    0: 정상 (normal 또는 warning만 존재)
    1: CRITICAL 세션 감지됨 (알림 목적)
"""

from __future__ import annotations

import argparse
import json
import sys
from pathlib import Path

# workspace root를 sys.path에 추가
_WORKSPACE_ROOT = Path(__file__).resolve().parent.parent
if str(_WORKSPACE_ROOT) not in sys.path:
    sys.path.insert(0, str(_WORKSPACE_ROOT))

from utils.logger import get_logger
from utils.session_monitor import get_active_sessions_status
from utils.session_resilience import SessionResilience

logger = get_logger(__name__)


def run_check(workspace_root: str | None = None) -> dict:
    """1회 체크: check_all_sessions() 호출 + 결과 반환.

    Args:
        workspace_root: 워크스페이스 루트 경로 (None이면 기본값 사용)

    Returns:
        SessionResilience.check_all_sessions() 결과:
        {
            "checked": N,
            "warnings": [...],
            "criticals": [...],
            "normals": N,
            "timestamp": "..."
        }
    """
    resilience = SessionResilience(workspace_root=workspace_root)
    result = resilience.check_all_sessions()
    logger.info(
        "run_check 완료: checked=%d, warnings=%d, criticals=%d",
        result["checked"],
        len(result["warnings"]),
        len(result["criticals"]),
    )
    return result


def run_status(workspace_root: str | None = None) -> dict:
    """현재 상태 조회: get_active_sessions_status() 결과 반환.
    대응 없이 상태만 보여줌.

    Args:
        workspace_root: 워크스페이스 루트 경로 (None이면 기본값 사용)

    Returns:
        {
            "sessions": [
                {
                    "task_id": "...",
                    "team_id": "...",
                    "total_tokens": N,
                    "limit": N,
                    "usage_pct": F,
                    "level": "normal"|"warning"|"critical"
                },
                ...
            ]
        }
    """
    if workspace_root is not None:
        memory_dir = Path(workspace_root) / "memory"
        timers_path = str(memory_dir / "task-timers.json")
        ledger_path = str(memory_dir / "token-ledger.json")
        result = get_active_sessions_status(
            timers_path=timers_path,
            ledger_path=ledger_path,
        )
    else:
        result = get_active_sessions_status()

    logger.info("run_status 완료: sessions=%d", len(result.get("sessions", [])))
    return result


def main(args: list[str] | None = None) -> int:
    """CLI 엔트리포인트.

    Args:
        args: CLI 인자 목록 (None이면 sys.argv 사용)

    Returns:
        exit code (0: 정상, 1: critical 감지)
    """
    parser = argparse.ArgumentParser(
        description="봇 세션 건강 상태 모니터링 워치독",
        prog="session_watchdog",
    )
    parser.add_argument(
        "--check",
        action="store_true",
        help="1회 체크 + 자동 대응 수행 후 JSON 출력",
    )
    parser.add_argument(
        "--status",
        action="store_true",
        help="현재 세션 상태만 출력 (대응 없음)",
    )
    parser.add_argument(
        "--workspace",
        type=str,
        default=None,
        metavar="PATH",
        help="워크스페이스 루트 경로 오버라이드 (테스트/디버그용)",
    )

    parsed = parser.parse_args(args)

    if not parsed.check and not parsed.status:
        parser.print_help()
        return 1

    workspace = parsed.workspace

    if parsed.check:
        result = run_check(workspace_root=workspace)
        print(json.dumps(result, ensure_ascii=False, indent=2))
        # critical이 하나라도 있으면 exit code 1
        if result.get("criticals"):
            return 1
        return 0

    if parsed.status:
        result = run_status(workspace_root=workspace)
        print(json.dumps(result, ensure_ascii=False, indent=2))
        return 0

    return 0


if __name__ == "__main__":
    sys.exit(main())
