"""Byte encoding utilities for PROTOCOL.

All byte values in JSON use hex string format: "0xHH" (uppercase, two digits).
Range: "0x00" through "0xFF".
"""

from __future__ import annotations

import re

# Pattern for hex byte format: 0x/0X followed by exactly two hex digits (case-insensitive)
HEX_BYTE_PATTERN = re.compile(r"^0[xX][0-9A-Fa-f]{2}$")


def encode_byte(value: int) -> str:
    """Encode an integer byte to hex string format.

    Args:
        value: Integer in range [0, 255]

    Returns:
        Hex string in format "0xHH" (uppercase)

    Raises:
        ValueError: If value is not in [0, 255]

    Example:
        >>> encode_byte(63)
        '0x3F'
        >>> encode_byte(0)
        '0x00'
        >>> encode_byte(255)
        '0xFF'
    """
    if not (0 <= value <= 255):
        raise ValueError(f"Byte value must be in [0, 255], got {value}")
    return f"0x{value:02X}"


def decode_byte(hex_str: str) -> int:
    """Decode hex string to integer byte.

    Args:
        hex_str: Hex string in format "0xHH" (case-insensitive input,
                 but canonical format is uppercase)

    Returns:
        Integer in range [0, 255]

    Raises:
        ValueError: If hex_str is not valid format

    Example:
        >>> decode_byte("0x3F")
        63
        >>> decode_byte("0x00")
        0
        >>> decode_byte("0xFF")
        255
    """
    if not HEX_BYTE_PATTERN.match(hex_str):
        raise ValueError(
            f"Invalid hex byte format: '{hex_str}'. Expected format: 0x[0-9A-F]{{2}} (e.g., '0x3F')"
        )
    return int(hex_str[2:], 16)


def is_valid_hex_byte(hex_str: str) -> bool:
    """Check if a string is a valid hex byte format.

    Args:
        hex_str: String to check

    Returns:
        True if valid hex byte format
    """
    return bool(HEX_BYTE_PATTERN.match(hex_str))


def encode_bytes(values: list[int]) -> list[str]:
    """Encode a list of bytes to hex strings.

    Args:
        values: List of integers in range [0, 255]

    Returns:
        List of hex strings
    """
    return [encode_byte(v) for v in values]


def decode_bytes(hex_strs: list[str]) -> list[int]:
    """Decode a list of hex strings to bytes.

    Args:
        hex_strs: List of hex strings

    Returns:
        List of integers
    """
    return [decode_byte(s) for s in hex_strs]
