__all__ = [
    'BasePoolMetric',
    'AssignmentEventsInPool',
    'AssignmentsInPool',
    'BansInPool',
    'PoolCompletedPercentage',
    'SpentBudgetOnPool',
    'TasksInPool',
    'WorkersByFilterOnPool',
]
import datetime
import toloka.async_client.client
import toloka.client
import toloka.metrics.metrics
import typing


class BasePoolMetric(toloka.metrics.metrics.BaseMetric):
    """Base class for all pool metrics
    """

    def __init__(
        self,
        pool_id: str,
        *,
        toloka_client: toloka.client.TolokaClient = None,
        atoloka_client: toloka.async_client.client.AsyncTolokaClient = None,
        timeout: datetime.timedelta = ...
    ) -> None:
        """Method generated by attrs for class BasePoolMetric.
        """
        ...

    toloka_client: toloka.client.TolokaClient
    atoloka_client: toloka.async_client.client.AsyncTolokaClient
    timeout: datetime.timedelta
    pool_id: str


class AssignmentEventsInPool(BasePoolMetric):
    """Tracking the change of response statuses in the pool.
    The metric is convenient for tracking that the pool is generally "alive" and working.
    If you want to track assignments counts, it's better to use AssignmentsInPool.

    Metrics starts gathering if they name are set. If the metric name is set to None, they don't gathering.

    Args:
        pool_id: From which pool track metrics.
        created_name: Metric name for a count of created events. Default None.
        submitted_name: Metric name for a count of submitted events. Default 'submitted_events_in_pool'.
        accepted_name : Metric name for a count of accepted events. Default 'accepted_events_in_pool'.
        rejected_name : Metric name for a count of rejected events. Default 'rejected_events_in_pool'.
        skipped_name: Metric name for a count of skipped events. Default None.
        expired_name: Metric name for a count of expired events. Default None.
        join_events: Count all events in one point.  Default False.

    Raises:
        ValueError: If all metric names are set to None or if there are duplicate metric names.

    Example:
        How to collect this metrics:
        >>> def print_metric(metric_dict):
        >>>     print(metric_dict)
        >>>
        >>> collector = MetricCollector([AssignmentEventsInPool(pool_id, toloka_client=toloka_client)], print_metric)
        >>> asyncio.run(collector.run())
        {
            'submitted_events_in_pool': [(datetime.datetime(2021, 8, 11, 15, 13, 4, 31000), 5)],
            'accepted_events_in_pool': [(datetime.datetime(2021, 8, 11, 15, 13, 3, 65000), 1)],
            'rejected_events_in_pool': [],
        }
    """

    def get_line_names(self) -> typing.List[str]:
        """Returns a list of metric names that can be generated by this class instance.
        """
        ...

    def __init__(
        self,
        pool_id: str,
        created_name: typing.Optional[str] = None,
        submitted_name: typing.Optional[str] = None,
        accepted_name: typing.Optional[str] = None,
        rejected_name: typing.Optional[str] = None,
        skipped_name: typing.Optional[str] = None,
        expired_name: typing.Optional[str] = None,
        join_events: bool = False,
        *,
        toloka_client: toloka.client.TolokaClient = None,
        atoloka_client: toloka.async_client.client.AsyncTolokaClient = None,
        timeout: datetime.timedelta = ...
    ) -> None:
        """Method generated by attrs for class AssignmentEventsInPool.
        """
        ...

    toloka_client: toloka.client.TolokaClient
    atoloka_client: toloka.async_client.client.AsyncTolokaClient
    timeout: datetime.timedelta
    pool_id: str
    _created_name: typing.Optional[str]
    _submitted_name: typing.Optional[str]
    _accepted_name: typing.Optional[str]
    _rejected_name: typing.Optional[str]
    _skipped_name: typing.Optional[str]
    _expired_name: typing.Optional[str]
    _join_events: bool


class PoolCompletedPercentage(BasePoolMetric):
    """Track pool completion in percentage

    You can't gather this metric from a pool with infinite task suites. For example, if you have infinite overlap on a pool.

    Args:
        pool_id: From which pool track metrics.
        percents_name: Metric name for pool completion percentage. Default 'completion_percentage'.
        toloka_client: Client for connection to Toloka. You can set toloka_client for several metrics via "bind_client" function.

    Example:
        How to collect this metric:
        >>> def print_metric(metric_dict):
        >>>     print(metric_dict)
        >>>
        >>> collector = MetricCollector([PoolCompletedPercentage(pool_id, toloka_client=toloka_client)], print_metric)
        >>> asyncio.run(collector.run())
        {
            'completion_percentage': [(datetime.datetime(2021, 8, 11, 15, 13, 4, 31000), 55)],
        }
    """

    def get_line_names(self) -> typing.List[str]:
        """Returns a list of metric names that can be generated by this class instance.
        """
        ...

    def __init__(
        self,
        pool_id: str,
        percents_name: typing.Optional[str] = None,
        *,
        toloka_client: toloka.client.TolokaClient = None,
        atoloka_client: toloka.async_client.client.AsyncTolokaClient = None,
        timeout: datetime.timedelta = ...
    ) -> None:
        """Method generated by attrs for class PoolCompletedPercentage.
        """
        ...

    toloka_client: toloka.client.TolokaClient
    atoloka_client: toloka.async_client.client.AsyncTolokaClient
    timeout: datetime.timedelta
    pool_id: str
    _percents_name: typing.Optional[str]


class AssignmentsInPool(BasePoolMetric):
    """Tracking the count of assignments in different states in the pool.

    Metrics starts gathering if they name are set. If the metric name is set to None, they don't gathering.

    Args:
        pool_id: From which pool track metrics.
        submitted_name: Metric name for a count of submitted assignments. Default 'submitted_assignments_in_pool'.
        accepted_name : Metric name for a count of accepted assignments. Default 'accepted_assignments_in_pool'.
        rejected_name : Metric name for a count of rejected assignments. Default 'rejected_assignments_in_pool'.
        skipped_name: Metric name for a count of skipped assignments. Default None.

    Raises:
        ValueError: If some metric has same names.

    Example:
        How to collect this metrics:
        >>> def print_metric(metric_dict):
        >>>     print(metric_dict)
        >>>
        >>> collector = MetricCollector([AssignmentsInPool(pool_id, toloka_client=toloka_client)], print_metric)
        >>> asyncio.run(collector.run())
        {
            'rejected_assignments_in_pool': [(datetime.datetime(2021, 8, 12, 10, 4, 44, 895232), 0)],
            'submitted_assignments_in_pool': [(datetime.datetime(2021, 8, 12, 10, 4, 45, 321904), 75)],
            'accepted_assignments_in_pool': [(datetime.datetime(2021, 8, 12, 10, 4, 45, 951156), 75)],
        }
    """

    def get_line_names(self) -> typing.List[str]:
        """Returns a list of metric names that can be generated by this class instance.
        """
        ...

    def __init__(
        self,
        pool_id: str,
        submitted_name: typing.Optional[str] = None,
        accepted_name: typing.Optional[str] = None,
        rejected_name: typing.Optional[str] = None,
        skipped_name: typing.Optional[str] = None,
        *,
        toloka_client: toloka.client.TolokaClient = None,
        atoloka_client: toloka.async_client.client.AsyncTolokaClient = None,
        timeout: datetime.timedelta = ...
    ) -> None:
        """Method generated by attrs for class AssignmentsInPool.
        """
        ...

    toloka_client: toloka.client.TolokaClient
    atoloka_client: toloka.async_client.client.AsyncTolokaClient
    timeout: datetime.timedelta
    pool_id: str
    _submitted_name: typing.Optional[str]
    _accepted_name: typing.Optional[str]
    _rejected_name: typing.Optional[str]
    _skipped_name: typing.Optional[str]


class TasksInPool(BasePoolMetric):
    """The number of tasks in the pool. Not new tasks. All tasks on each step.

    Args:
        pool_id: From which pool track metrics.
        tasks_name: Metric name for a count of tasks.

    Example:
        How to collect this metrics:
        >>> def print_metric(metric_dict):
        >>>     print(metric_dict)
        >>>
        >>> collector = MetricCollector([TasksInPool(pool_id, toloka_client=toloka_client)], print_metric)
        >>> asyncio.run(collector.run())
        {
            'tasks_count': [(datetime.datetime(2021, 11, 18, 9, 36, 34, 163000), 40)],
        }
    """

    def get_line_names(self) -> typing.List[str]:
        """Returns a list of metric names that can be generated by this class instance.
        """
        ...

    def __init__(
        self,
        pool_id: str,
        tasks_name: typing.Optional[str] = None,
        *,
        toloka_client: toloka.client.TolokaClient = None,
        atoloka_client: toloka.async_client.client.AsyncTolokaClient = None,
        timeout: datetime.timedelta = ...
    ) -> None:
        """Method generated by attrs for class TasksInPool.
        """
        ...

    toloka_client: toloka.client.TolokaClient
    atoloka_client: toloka.async_client.client.AsyncTolokaClient
    timeout: datetime.timedelta
    pool_id: str
    _tasks_name: typing.Optional[str]


class SpentBudgetOnPool(BasePoolMetric):
    """How much money has already been spent on this pool, excluding fee.

    Args:
        pool_id: From which pool track metrics.
        tasks_name: Metric name for a count of tasks.

    Example:
        How to collect this metrics:
        >>> def print_metric(metric_dict):
        >>>     print(metric_dict)
        >>>
        >>> collector = MetricCollector([SpentBudgetOnPool(pool_id, toloka_client=toloka_client)], print_metric)
        >>> asyncio.run(collector.run())
        {
            'spent_money': [(datetime.datetime(2021, 11, 18, 9, 36, 34, 163000), Decimal('0.3'))],
        }
    """

    def get_line_names(self) -> typing.List[str]:
        """Returns a list of metric names that can be generated by this class instance.
        """
        ...

    def __init__(
        self,
        pool_id: str,
        money_name: typing.Optional[str] = None,
        *,
        toloka_client: toloka.client.TolokaClient = None,
        atoloka_client: toloka.async_client.client.AsyncTolokaClient = None,
        timeout: datetime.timedelta = ...
    ) -> None:
        """Method generated by attrs for class SpentBudgetOnPool.
        """
        ...

    toloka_client: toloka.client.TolokaClient
    atoloka_client: toloka.async_client.client.AsyncTolokaClient
    timeout: datetime.timedelta
    pool_id: str
    _money_name: typing.Optional[str]


class WorkersByFilterOnPool(BasePoolMetric):
    """The number of active performers matching the pool filters for the last hours (default 1 hour)

    Args:
        pool_id: From which pool track metrics.
        workers_name: Metric name for a count of workers.
        interval_hours: Counts unical workers on this hours interval. Default 1.

    Example:
        How to collect this metrics:
        >>> def print_metric(metric_dict):
        >>>     print(metric_dict)
        >>>
        >>> collector = MetricCollector([WorkersByFilterOnPool(pool_id, toloka_client=toloka_client)], print_metric)
        >>> asyncio.run(collector.run())
        {
            'workers_count': [(datetime.datetime(2021, 11, 18, 9, 36, 34, 163000), 2697)],
        }
    """

    def get_line_names(self) -> typing.List[str]:
        """Returns a list of metric names that can be generated by this class instance.
        """
        ...

    def __init__(
        self,
        pool_id: str,
        workers_name: typing.Optional[str] = None,
        interval_hours: int = 1,
        *,
        toloka_client: toloka.client.TolokaClient = None,
        atoloka_client: toloka.async_client.client.AsyncTolokaClient = None,
        timeout: datetime.timedelta = ...
    ) -> None:
        """Method generated by attrs for class WorkersByFilterOnPool.
        """
        ...

    toloka_client: toloka.client.TolokaClient
    atoloka_client: toloka.async_client.client.AsyncTolokaClient
    timeout: datetime.timedelta
    pool_id: str
    _workers_name: typing.Optional[str]
    _interval_hours: int


class BansInPool(BasePoolMetric):
    """Tracking the new user restrictions in pool

    Be careful: if you set in quality controls to ban performers 'on project', bans 'on pool' will never happen.

    Args:
        pool_id: From which pool track metrics.
        count_name: Metric name for a count of bans.
        filter_by_comment: Allow to split user restriction into several lines based on comment.
            Dictionary where, key - comment string, and value - name for line in which will be aggregated bans with this comments.
        join_events: Count all events in one point.  Default False.

    Example:
        How to collect this metrics:
        >>> def print_metric(metric_dict):
        >>>     print(metric_dict)
        >>>
        >>> collector = MetricCollector([BansInPool(pool_id, toloka_client=toloka_client)], print_metric)
        >>> asyncio.run(collector.run())
        {
            'bans_count': [(datetime.datetime(2021, 11, 18, 13, 30, 11, 522000), 1)],
        }

        How to split bans onto several metrics.
        >>> collector = MetricCollector(
        >>>     [
        >>>         BansInPool(
        >>>             pool_id,
        >>>             toloka_client=toloka_client,
        >>>             filter_by_comment={'fast answers': 'fast', 'bad quality on honeypots': 'honeypots'}
        >>>         ),
        >>>     ],
        >>>     print_metric
        >>> )
        >>> asyncio.run(collector.run())
        {
            'honeypots': [(datetime.datetime(2021, 11, 18, 13, 32, 52, 475000), 1)],
            'fast': [(datetime.datetime(2021, 11, 18, 13, 32, 50, 453000), 1)],
        }
    """

    def get_line_names(self) -> typing.List[str]:
        """Returns a list of metric names that can be generated by this class instance.
        """
        ...

    def __init__(
        self,
        pool_id: str,
        count_name: typing.Optional[str] = None,
        filter_by_comment: typing.Optional[typing.Dict[str, str]] = None,
        join_events: bool = False,
        *,
        toloka_client: toloka.client.TolokaClient = None,
        atoloka_client: toloka.async_client.client.AsyncTolokaClient = None,
        timeout: datetime.timedelta = ...
    ) -> None:
        """Method generated by attrs for class BansInPool.
        """
        ...

    toloka_client: toloka.client.TolokaClient
    atoloka_client: toloka.async_client.client.AsyncTolokaClient
    timeout: datetime.timedelta
    pool_id: str
    _count_name: typing.Optional[str]
    _filter_by_comment: typing.Optional[typing.Dict[str, str]]
    _join_events: bool
