from abc import ABCMeta, abstractmethod

import trio

from dstat_interface.core.experiments.experiment_container import ExperimentContainer


class BaseTasks(object, metaclass=ABCMeta):
    def __init__(self):
        self.tasks = []

    async def loop(self):
        async with trio.open_nursery() as nursery:
            for task in self.tasks:
                nursery.start_soon(task, nursery.cancel_scope)


class ExperimentBaseTasks(BaseTasks):
    def __init__(self, exp_con: ExperimentContainer):
        super().__init__()
        self.exp_con = exp_con
        self.tasks += [self.update_progress, self.exp_runner]

    @abstractmethod
    async def update_progress(self, cancel_scope: trio.CancelScope):
        pass

    async def exp_runner(self, cancel_scope: trio.CancelScope):
        while True:
            if not self.exp_con.handler_instance.experiment_running_data():
                return
            if not self.exp_con.handler_instance.experiment_running_proc():
                self.exp_con.handler_instance.get_all_data()
                return
            await trio.sleep(0)
