# -*- coding: utf-8 -*-
from concurrent.futures import FIRST_COMPLETED, ThreadPoolExecutor, wait
from typing import Any, Callable, List

from tqdm import tqdm

from ddans.common.type import T

TQDM_FORMAT = "{l_bar}{bar}| {n_fmt}/{total_fmt}{unit} [{elapsed}]"


class Pbar:

    @staticmethod
    def list(items: List[T],
             func: Callable[[T], Any],
             desc: str = "",
             max=1,
             unit=""):
        futures = []
        with ThreadPoolExecutor(max_workers=max) as executor:
            for item in items:
                futures.append(executor.submit(func, item))
            pbar = tqdm(total=len(futures),
                        desc=desc,
                        disable=False,
                        unit=unit,
                        ncols=80,
                        bar_format=TQDM_FORMAT,
                        colour="cyan")
            while futures:
                done, futures = wait(futures, return_when=FIRST_COMPLETED)
                for future in done:
                    try:
                        future.result()  # 检查异常，但不阻塞
                    except Exception:
                        pass
                    pbar.update(1)
            pbar.close()
