"""Tool: cloudsense_diagnostics -- server health check and log inspection."""

import json
import platform
import subprocess
import sys
from pathlib import Path
from typing import Any, Dict, List

from ..logging_config import get_log_file_path, get_system_info, SESSION_ID

TOOL_NAME = "cloudsense_diagnostics"

TOOL_DEFINITION = {
    "name": TOOL_NAME,
    "description": (
        "Run diagnostics on the CloudSense DX MCP server. "
        "Returns server version, Python version, OS, sf CLI version, "
        "log file location and size, recent tool call history, and "
        "Salesforce org connectivity status. "
        "Use when troubleshooting issues or checking server health."
    ),
    "inputSchema": {
        "type": "object",
        "properties": {
            "include_recent_logs": {
                "type": "boolean",
                "description": "Include the last 20 tool call log entries. Default: true.",
                "default": True,
            },
            "check_org_connectivity": {
                "type": "boolean",
                "description": (
                    "Test connectivity to the current Salesforce org "
                    "by running sf org display. Default: false."
                ),
                "default": False,
            },
        },
        "required": [],
    },
}


def _get_sf_cli_version() -> str:
    try:
        r = subprocess.run(
            ["sf", "--version"], capture_output=True, text=True, timeout=10
        )
        if r.returncode == 0:
            return r.stdout.strip().split("\n")[0]
        return f"error (exit {r.returncode})"
    except FileNotFoundError:
        return "not installed"
    except subprocess.TimeoutExpired:
        return "timeout"
    except Exception as e:
        return f"error: {e}"


def _get_log_info() -> Dict[str, Any]:
    log_path = get_log_file_path()
    info: Dict[str, Any] = {"path": str(log_path), "exists": log_path.exists()}
    if log_path.exists():
        stat = log_path.stat()
        info["size_bytes"] = stat.st_size
        info["size_human"] = _human_size(stat.st_size)

        backups = sorted(log_path.parent.glob(f"{log_path.name}.*"))
        info["backup_files"] = len(backups)
        total = stat.st_size + sum(b.stat().st_size for b in backups)
        info["total_size_human"] = _human_size(total)
    return info


def _human_size(nbytes: int) -> str:
    for unit in ("B", "KB", "MB", "GB"):
        if nbytes < 1024:
            return f"{nbytes:.1f} {unit}"
        nbytes /= 1024
    return f"{nbytes:.1f} TB"


def _read_recent_tool_calls(count: int = 20) -> List[Dict]:
    log_path = get_log_file_path()
    if not log_path.exists():
        return []

    entries: List[Dict] = []
    try:
        with open(log_path, "r", encoding="utf-8") as f:
            for line in f:
                line = line.strip()
                if not line:
                    continue
                try:
                    obj = json.loads(line)
                except json.JSONDecodeError:
                    continue
                if obj.get("event") == "tool_call":
                    entries.append(obj)
    except Exception:
        return []

    return entries[-count:]


def _check_org_connectivity() -> Dict[str, Any]:
    try:
        r = subprocess.run(
            ["sf", "org", "display", "--json"],
            capture_output=True, text=True, timeout=20,
        )
        data = json.loads(r.stdout)
        if r.returncode == 0:
            info = data.get("result", {})
            return {
                "reachable": True,
                "org_alias": info.get("alias", ""),
                "username": info.get("username", ""),
                "instance_url": info.get("instanceUrl", ""),
                "api_version": info.get("apiVersion", ""),
            }
        return {
            "reachable": False,
            "error": data.get("message", "unknown error"),
        }
    except FileNotFoundError:
        return {"reachable": False, "error": "sf CLI not installed"}
    except subprocess.TimeoutExpired:
        return {"reachable": False, "error": "sf org display timed out"}
    except Exception as e:
        return {"reachable": False, "error": str(e)}


async def execute(arguments: Dict[str, Any]) -> str:
    """Execute the cloudsense_diagnostics tool."""
    from ..server import _CURRENT_VERSION

    include_logs = arguments.get("include_recent_logs", True)
    check_org = arguments.get("check_org_connectivity", False)

    result: Dict[str, Any] = {
        "success": True,
        "server": {
            "version": _CURRENT_VERSION,
            "session_id": SESSION_ID,
            **get_system_info(),
        },
        "sf_cli": {
            "version": _get_sf_cli_version(),
        },
        "logging": _get_log_info(),
    }

    if include_logs:
        recent = _read_recent_tool_calls(20)
        result["recent_tool_calls"] = {
            "count": len(recent),
            "entries": recent,
        }

    if check_org:
        result["org_connectivity"] = _check_org_connectivity()

    return json.dumps(result, indent=2)
