import itertools


def combine_bucket(
        parts: list,
        threshold: int,
        truncate: bool = False,
        keep_remain: bool = False) -> list:
    """
    Convert parts to buckets with given length(threshold).

    Parameters
    ----------
    parts: the given parts.
    threshold: bucket length.
    truncate: whether to truncate those whose length is bigger than threshold.
    keep_remain: when truncate=True, whether to keep the remain parts.

    Returns
    out: list of bucket.
    -------
    """
    def deal_long_part(part: str) -> list:
        result = []
        if truncate:
            if keep_remain:
                len_subparts = len(part) // threshold + 1
                for i in range(len_subparts):
                    sub_part = part[i*threshold: (i+1)*threshold]
                    if sub_part:
                        result.append(sub_part)
            else:
                result.append(part[:threshold])
        else:
            result.append(part)
        return result

    buckets = []
    while parts:
        part = parts.pop(0)
        # directly add to buckets when a part is longer than threshold
        if len(part) > threshold:
            sub_parts = deal_long_part(part)
            buckets.append(sub_parts)
        else:
            while parts and len(part) < threshold:
                another = parts[0]
                if len(part + another) > threshold:
                    break
                else:
                    part += parts.pop(0)
            buckets.append([part])
    result = list(itertools.chain(*buckets))
    return result