from __future__ import annotations

import importlib.util
import json
from pathlib import Path


MODULE = Path(__file__).parents[2] / "plugins" / "1c" / "observer" / "observer_server.py"
SPEC = importlib.util.spec_from_file_location("adapter_observer", MODULE)
assert SPEC and SPEC.loader
observer = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(observer)


def test_summary_separates_expected_rejection_and_exception() -> None:
    events = [
        {"event": "adapter_rpc", "time": "2026-08-07T10:00:00Z", "request_id": "a", "method": "metadata.form.decode", "request": {"base_id": "upo_test", "ref": "Document.X"}, "status": "ok", "duration_ms": 100},
        {"event": "adapter_rpc", "time": "2026-08-07T10:01:00Z", "request_id": "b", "method": "metadata.form.decode", "request": {"base_id": "upo_test"}, "status": "partial", "error": "time_budget_exhausted", "duration_ms": 6000},
        {"event": "adapter_rpc", "time": "2026-08-07T10:02:00Z", "request_id": "c", "method": "modules.read", "request": {"base_id": "upo_test"}, "status": "exception", "error": "request_exception", "duration_ms": 10},
        {"event": "adapter_rpc", "time": "2026-08-07T10:03:00Z", "request_id": "d", "method": "adapter.job.get", "request": {"base_id": "upo_test"}, "status": "running", "duration_ms": 1},
    ]
    result = observer.build_summary(events, 0)
    assert result["events"] == 4
    assert result["exceptions"] == 1
    assert result["p95_ms"] == 6000
    assert any(item["error"] == "time_budget_exhausted" for item in result["findings"])
    assert not any(item["status"] == "running" for item in result["findings"])
    assert "BSL" not in json.dumps(observer.event_view(events[0]), ensure_ascii=False)


def test_correlations_keep_mcp_request_that_did_not_reach_rest() -> None:
    rest = [{"request_id": "same", "method": "modules.read", "status": "ok", "duration_ms": 20}]
    mcp = [{"request_id": "same", "method": "modules.read", "status": "ok", "duration_ms": 30}, {"request_id": "lost", "method": "modules.read", "status": "exception", "error": "adapter_unavailable"}]
    result = observer.correlations(rest, mcp)
    assert result[0]["correlation_status"] == "not_reached_rest"
    assert result[1]["correlation_status"] == "matched"
