def build_info_str(username: str, name_len: int, remaining_chip: int, action: str,
                   chip: int, is_waiting: bool, countdown: int) -> str:
    """Build a string to explain action of a user

    Args:
        username (str): user name
        name_len (int): characters to show the name
        remaining_chip (int): remaining chip of the user
        action (str): the action being taken, should be one of the
            following: check, bet, raise, all-in, fold
            The differences of `bet` and `raise` are that `bet` is
            the first put-chip action, while `raise` is another
            put-chip action against prior `bet`
        chip (int): the chip of an action, only meaningful when
            `action` is `bet`, `raise` or `all-in`
        is_waiting (bool): a flag that indicate if this user is in
            execution position
        countdown (int): the countdown of waiting, only meaningful
            when `is_waiting` is `True`

    Return:
        info_str (str): a string to explain action of a user
    """
    info = f"{username:{name_len}} (${str(remaining_chip) + ')':<5} {action}"
    if action in ("bet", "raise", "all-in"):
        info += f" ${chip}    "
    if is_waiting:
        info += f"{countdown}s"
        info = "-> " + info
    else:
        info = "   " + info
    return info