from dataclasses import dataclass
from typing import Iterable, Iterator

import axipy


class _ProgressWithStepMixIn:
    @dataclass
    class ProgressState:
        progress_max: int = 1000
        one_step: int = 1
        step_needed: bool = False
        n: int = 0

    # noinspection PyAttributeOutsideInit
    def init_progress_with_step(self, task: axipy.Task, count: int) -> None:
        self.__progress_state = self.ProgressState()
        self.__task = task

        if count > self.__progress_state.progress_max:
            self.__progress_state.one_step = count // self.__progress_state.progress_max
            self.__progress_state.step_needed = True

        if self.__progress_state.step_needed:
            new_max = self.__progress_state.progress_max
        else:
            new_max = count

        self.__task.range = self.__task.Range(0, new_max)

    def add_value_progress_with_step(self) -> None:
        if self.__progress_state.step_needed:
            self.__progress_state.n += 1
            if self.__progress_state.n % self.__progress_state.one_step == 0:
                self.__task.value += 1
        else:
            self.__task.value += 1

    def init_feature_iter_with_progress(self, items: Iterable[axipy.Feature]) -> Iterator[axipy.Feature]:
        for f in items:
            self.__task.raise_if_canceled()
            self.add_value_progress_with_step()
            yield f
