"""PeerDrop Utils — Length-prefix framing for IPC messages."""

from __future__ import annotations

import struct

# Maximum accepted IPC message size (64 MiB). Guards against malicious or
# corrupt length headers causing unbounded buffer growth on the daemon.
MAX_MESSAGE_SIZE = 64 * 1024 * 1024


def length_prefix_pack(data: bytes) -> bytes:
    """Length-prefix a message (4-byte big-endian header + payload)."""
    return struct.pack(">I", len(data)) + data


def length_prefix_unpack(buffer: bytes) -> tuple[bytes, bytes] | None:
    """Unpack one length-prefixed message from buffer.

    Returns (message, remaining) or None if incomplete.
    Raises ValueError if the length header exceeds MAX_MESSAGE_SIZE.
    """
    if len(buffer) < 4:
        return None
    (msg_len,) = struct.unpack(">I", buffer[:4])
    if msg_len > MAX_MESSAGE_SIZE:
        raise ValueError(
            f"Message length {msg_len} exceeds maximum {MAX_MESSAGE_SIZE}"
        )
    if len(buffer) < 4 + msg_len:
        return None
    return buffer[4 : 4 + msg_len], buffer[4 + msg_len :]
