"""Tests for exec detail failure grouping keys (mirrors frontend execDetailGrouping.ts rule B)."""

import re


def strip_dynamic_error_parts(text: str) -> str:
    text = re.sub(r"\b\d{1,3}(?:\.\d{1,3}){3}\b", "<ip>", text)
    text = re.sub(r":\d{2,5}\b", ":<port>", text)
    text = re.sub(r"/[^\s'\"]+", "/<path>", text)
    text = re.sub(
        r"\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b",
        "<uuid>",
        text,
        flags=re.I,
    )
    return re.sub(r"\s+", " ", text).strip()


def normalize_exec_error_key(summary: str) -> str:
    trimmed = summary.strip()
    if not trimmed or trimmed == "—":
        return "未知错误"
    first_line = trimmed.split("\n", 1)[0].strip() or trimmed
    normalized = strip_dynamic_error_parts(first_line)
    return (normalized[:200] or "未知错误")


def test_same_ssh_timeout_different_ips_merge():
    a = "ssh: connect to host 1.2.3.4 port 22: Connection timed out"
    b = "ssh: connect to host 5.6.7.8 port 22: Connection timed out"
    assert normalize_exec_error_key(a) == normalize_exec_error_key(b)


def test_different_errors_stay_separate():
    a = normalize_exec_error_key("Permission denied (publickey)")
    b = normalize_exec_error_key("Connection timed out")
    assert a != b


def test_empty_summary():
    assert normalize_exec_error_key("—") == "未知错误"
    assert normalize_exec_error_key("   ") == "未知错误"
