from __future__ import annotations

import json
import sys
from typing import Any

from e2e_automation_core import allure_summary, build_plan, inspect_accounts, latest_bugs, list_tests, run_pytest


TOOLS = [
    {
        "name": "list_tests",
        "description": "List pytest E2E test files and markers. Optional marker filters by pytest marker.",
        "inputSchema": {
            "type": "object",
            "properties": {"marker": {"type": "string"}},
        },
    },
    {
        "name": "inspect_accounts",
        "description": "Read runtime/e2e_accounts.json and summarize available ledger states.",
        "inputSchema": {"type": "object", "properties": {}},
    },
    {
        "name": "latest_bugs",
        "description": "List recent bug markdown reports and screenshots from bugs/.",
        "inputSchema": {
            "type": "object",
            "properties": {"limit": {"type": "integer", "default": 5}},
        },
    },
    {
        "name": "allure_summary",
        "description": "Summarize the latest Allure report or raw result statuses.",
        "inputSchema": {"type": "object", "properties": {}},
    },
    {
        "name": "build_plan",
        "description": "Build a run plan for a profile such as seed, standalone, chain, main, saas-001, auth, push, order.",
        "inputSchema": {
            "type": "object",
            "properties": {"profile": {"type": "string", "default": "standalone"}},
        },
    },
    {
        "name": "run_pytest",
        "description": "Run pytest for a profile and write Allure raw results.",
        "inputSchema": {
            "type": "object",
            "properties": {
                "profile": {"type": "string", "default": "standalone"},
                "extra_args": {"type": "array", "items": {"type": "string"}},
                "env": {"type": "object", "additionalProperties": {"type": "string"}},
            },
        },
    },
]


def _content(payload: Any) -> dict[str, Any]:
    return {"content": [{"type": "text", "text": json.dumps(payload, ensure_ascii=False, indent=2)}]}


def _call_tool(name: str, arguments: dict[str, Any]) -> dict[str, Any]:
    if name == "list_tests":
        return _content(list_tests(arguments.get("marker")))
    if name == "inspect_accounts":
        return _content(inspect_accounts())
    if name == "latest_bugs":
        return _content(latest_bugs(int(arguments.get("limit", 5))))
    if name == "allure_summary":
        return _content(allure_summary())
    if name == "build_plan":
        return _content(build_plan(arguments.get("profile", "standalone")))
    if name == "run_pytest":
        return _content(run_pytest(arguments.get("profile", "standalone"), arguments.get("extra_args"), arguments.get("env")))
    raise ValueError(f"Unknown tool: {name}")


def handle(request: dict[str, Any]) -> dict[str, Any] | None:
    method = request.get("method")
    request_id = request.get("id")
    if method == "notifications/initialized":
        return None
    if method == "initialize":
        result = {
            "protocolVersion": "2024-11-05",
            "capabilities": {"tools": {}},
            "serverInfo": {"name": "saas-e2e", "version": "0.1.0"},
        }
    elif method == "tools/list":
        result = {"tools": TOOLS}
    elif method == "tools/call":
        params = request.get("params", {})
        result = _call_tool(params.get("name", ""), params.get("arguments", {}) or {})
    else:
        return {"jsonrpc": "2.0", "id": request_id, "error": {"code": -32601, "message": f"Method not found: {method}"}}
    return {"jsonrpc": "2.0", "id": request_id, "result": result}


def main() -> int:
    for line in sys.stdin:
        if not line.strip():
            continue
        try:
            response = handle(json.loads(line))
        except Exception as exc:
            response = {"jsonrpc": "2.0", "id": None, "error": {"code": -32000, "message": str(exc)}}
        if response is not None:
            print(json.dumps(response, ensure_ascii=False), flush=True)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
