"""
Supreme 2 MAX — MCP Resources

Each resource is registered via ``@mcp.resource()`` decorator and returns
the file contents as a string.

URI scheme::

    supreme2l://scans/latest           → JSON string  (latest scan result)
    supreme2l://scans/{scan_id}        → JSON string  (specific scan result)
    supreme2l://scans/{scan_id}/report → JSON string  (generated report)
    supreme2l://config                 → YAML string  (project configuration)
    supreme2l://scanners               → JSON string  (available scanners list)
"""

from __future__ import annotations

import json
from pathlib import Path
from typing import Any, Dict, Optional

import yaml

from supreme_max.config import ConfigManager
from supreme_max.mcp_server._server import mcp
from supreme_max.mcp_server.state import ScanStateManager
from supreme_max.scanners import registry as scanner_registry

# ---------------------------------------------------------------------------
# Singleton state manager — shared with tools.py via lazy init.
# ---------------------------------------------------------------------------

_state_manager: Optional[ScanStateManager] = None


def _get_state_manager() -> ScanStateManager:
    global _state_manager
    if _state_manager is None:
        _state_manager = ScanStateManager()
    return _state_manager


# ---------------------------------------------------------------------------
# Resource handlers (registered via decorators)
# ---------------------------------------------------------------------------

@mcp.resource("supreme2l://scans/latest")
async def resource_scans_latest() -> str:
    """Latest scan results as JSON."""
    state = _get_state_manager()
    scan_result = state.get_latest_scan()

    if scan_result is None:
        return json.dumps({"error": "No scans found"}, indent=2)

    return json.dumps(scan_result, indent=2, default=str)


@mcp.resource("supreme2l://scans/{scan_id}")
async def resource_scan_by_id(scan_id: str) -> str:
    """Specific scan results by ID."""
    state = _get_state_manager()
    scan_result = state.get_scan(scan_id)

    if scan_result is None:
        return json.dumps({"error": f"Scan '{scan_id}' not found"}, indent=2)

    return json.dumps(scan_result, indent=2, default=str)


@mcp.resource("supreme2l://scans/{scan_id}/report")
async def resource_scan_report(scan_id: str) -> str:
    """Generated report for a scan.

    The report path is looked up from the database.  The file contents
    are read and returned verbatim.
    """
    state = _get_state_manager()
    meta = state.get_scan_metadata(scan_id)

    if meta is None:
        return json.dumps({"error": f"Scan '{scan_id}' not found"}, indent=2)

    report_path_str: Optional[str] = meta.get("report_path")
    if not report_path_str:
        return json.dumps(
            {"error": f"No report generated yet for scan '{scan_id}'. "
                      "Use the generate_report tool first."},
            indent=2,
        )

    report_path = Path(report_path_str)
    if not report_path.is_file():
        return json.dumps(
            {"error": f"Report file not found at '{report_path}'"},
            indent=2,
        )

    # Return the raw file content — it's already JSON.
    return report_path.read_text(encoding="utf-8")


@mcp.resource("supreme2l://config")
async def resource_config() -> str:
    """Project configuration as YAML."""
    config = ConfigManager.load_config()
    return yaml.dump(
        config.to_dict(),
        default_flow_style=False,
        sort_keys=False,
        indent=2,
    )


@mcp.resource("supreme2l://scanners")
async def resource_scanners() -> str:
    """Available scanners list as JSON."""
    scanners_info = []
    for scanner in scanner_registry.get_all_scanners():
        scanners_info.append({
            "name": scanner.name,
            "tool": scanner.tool_name,
            "extensions": scanner.get_file_extensions(),
            "available": scanner.is_available(),
        })

    return json.dumps(scanners_info, indent=2)
