import re

_EMAIL_PATTERN = re.compile(r"[^@\s]+@[^@\s]+\.[^@\s]+")
_GENERIC_SESSION_NAMES = {
    "AthenaJWT",
    "aws-go-sdk",
    "aws-sdk-java",
    "botocore-session",
}


def _looks_like_email(value: str | None) -> bool:
    return bool(value and _EMAIL_PATTERN.fullmatch(value))


def _principal_suffix(principal_id: str | None) -> str | None:
    if not principal_id or ":" not in principal_id:
        return None

    return principal_id.split(":", 1)[1]


def _normalized_technical_identity(
    principal_suffix: str | None,
    session_issuer_user_name: str | None,
) -> str | None:
    if not principal_suffix:
        return None

    normalized_suffix = re.sub(r"-\d{6,}$", "", principal_suffix)
    if normalized_suffix in _GENERIC_SESSION_NAMES:
        return session_issuer_user_name or None

    if normalized_suffix != principal_suffix:
        return normalized_suffix

    return None


def _first_email(values: list[str | None]) -> str | None:
    for value in values:
        if _looks_like_email(value):
            return value
    return None


def parse_cloudtrail_user(cloudtrail_event: dict) -> dict[str, str | None]:
    """
    Extract one canonical actor identity from a CloudTrail event.

    The exact user fields vary depending on whether the query was run through
    an IAM user, an assumed role, or a federated identity. We normalize those
    variants into a single identifier that can be reused consistently as both
    `user_id` and `user_name` in downstream query analytics.

    Examples:
    - ``principalId = "AROA...:alice.analyst@example.com"`` becomes
      ``user_id = user_name = user_email = "alice.analyst@example.com"``

    - ``principalId = "AROA...:botocore-session-1773536400000"`` with
      ``sessionIssuer.userName = "team-role"`` becomes
      ``user_id = user_name = "team-role"``
    """

    user_identity = cloudtrail_event.get("userIdentity") or {}
    session_context = user_identity.get("sessionContext") or {}
    session_issuer = session_context.get("sessionIssuer") or {}
    on_behalf_of = user_identity.get("onBehalfOf") or {}
    principal_id = user_identity.get("principalId")
    principal_suffix = _principal_suffix(principal_id)
    user_name = user_identity.get("userName")
    session_issuer_user_name = session_issuer.get("userName")
    normalized_technical_identity = _normalized_technical_identity(
        principal_suffix,
        session_issuer_user_name,
    )

    # Prefer human-looking identities when CloudTrail exposes them through an
    # assumed-role session, so frequent-user and popularity computations are
    # grouped by person rather than by session identifier or role name.
    human_identity = on_behalf_of.get("userId") or _first_email(
        [
            principal_suffix,
            user_name,
            session_issuer_user_name,
        ]
    )
    technical_identity = (
        normalized_technical_identity
        or principal_id
        or user_identity.get("arn")
        or session_issuer.get("arn")
        or session_issuer_user_name
    )
    canonical_user_id = human_identity or technical_identity

    user_email = (
        canonical_user_id if _looks_like_email(canonical_user_id) else None
    )

    return {
        "user_email": user_email,
        "user_id": canonical_user_id,
        "user_name": canonical_user_id,
    }
