import socket
import struct


def format_ipv4(ip, port=None):
    """Format an ipv4 address into a human-readable string.

    Args:
        ip (varies): the ip address as extracted in an LTTng event.
        Either an integer or a list of integers, depending on the
        tracer version.

        port (int, optional): the port number associated with the
        address.

    Returns:
        The formatted string containing the ipv4 address and, optionally,
        the port number.

    """
    # depending on the version of lttng-modules, the v4addr is an
    # integer (< 2.6) or sequence (>= 2.6)
    try:
        ip_str = '{}.{}.{}.{}'.format(ip[0], ip[1], ip[2], ip[3])
    except TypeError:
        # The format string '!I' tells pack to interpret ip as a
        # packed structure of network-endian 32-bit unsigned integers,
        # which inet_ntoa can then convert into the formatted string
        ip_str = socket.inet_ntoa(struct.pack('!I', ip))

    if port is not None:
        ip_str += ':{}'.format(port)

    return ip_str