# coding:utf-8

import functools
import gevent
from utils.gevent_util import init_tracer, wrap_tracer


class TaskExist(Exception):
    """任务存在"""


class TaskNotExist(Exception):
    """任务不存在"""


class Tasks(dict):
    """任务集合"""

    def __init__(self, trace_info=None):
        self.tasks = {}
        self.task_list = []
        if not trace_info:
            self.trace_info = init_tracer()
        else:
            self.trace_info = trace_info

    def raise_exist(self, name):

        if name in self:
            raise TaskExist("Task {} exist.".format(name))

    def raise_not_exist(self, name):

        if name not in self:
            raise TaskNotExist("Task {} does not exist.".format(name))

    def add(self, name, func, *args, **kwargs):
        """添加任务"""

        self.raise_exist(name)

        wrap_task = wrap_tracer(**self.trace_info)(func)
        task = gevent.spawn(wrap_task, *args, **kwargs)

        self.tasks[name] = task
        self.task_list.append(task)

    @property
    def jobs(self):

        values = {}
        for name, task in self.tasks.items():
            value = task.value
            if not value:
                task.join()
            values[name] = task.value

        return values

    def joinall(self):
        gevent.joinall(self.task_list)

    def get_val(self, name):

        self.raise_not_exist(name)

        return self[name].value
