import itertools


def pack_types(types, args, major):
    """Pack arguments according the the types list.

    Parameters
    ----------
    types : sequence of kattypes
        The types of the arguments (in order).
    args : sequence of objects
        The arguments to format.
    major : integer
        Major version of KATCP to use when packing types

    Returns
    -------
    packed_args : list
        List of args after packing to byte strings
    """
    if len(types) > 0:
        multiple = types[-1]._multiple
    else:
        multiple = False

    if len(types) < len(args) and not multiple:
        raise ValueError("Too many arguments to pack.")

    if len(args) < len(types):
        # zip_longest will use None for missing args
        retvals = [ktype.pack(arg, major=major)
                   for ktype, arg in itertools.zip_longest(types, args)]
    else:
        retvals = [ktype.pack(arg, major=major)
                   for ktype, arg in zip(types, args)]

    if len(args) > len(types) and multiple:
        last_ktype = types[-1]
        for arg in args[len(types):]:
            retvals.append(last_ktype.pack(arg, major=major))

    return retvals