# Copyright 1999-2018 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

from _emerge.AsynchronousTask import AsynchronousTask
from portage import os


class CompositeTask(AsynchronousTask):

    __slots__ = ("_current_task",)

    _TASK_QUEUED = -1

    def _cancel(self):
        if self._current_task is not None:
            if self._current_task is self._TASK_QUEUED:
                self.returncode = 1
                self._current_task = None
                self._async_wait()
            else:
                self._current_task.cancel()
        elif self.returncode is None:
            # Assume that the task has not started yet.
            self._was_cancelled()
            self._async_wait()

    def _poll(self):
        """
        This does a loop calling self._current_task.poll()
        repeatedly as long as the value of self._current_task
        keeps changing. It calls poll() a maximum of one time
        for a given self._current_task instance. This is useful
        since calling poll() on a task can trigger advance to
        the next task could eventually lead to the returncode
        being set in cases when polling only a single task would
        not have the same effect.
        """

        prev = None
        while True:
            task = self._current_task
            if task is None or task is self._TASK_QUEUED or task is prev:
                # don't poll the same task more than once
                break
            task.poll()
            prev = task

        return self.returncode

    def _assert_current(self, task):
        """
        Raises an AssertionError if the given task is not the
        same one as self._current_task. This can be useful
        for detecting bugs.
        """
        if task is not self._current_task:
            raise AssertionError("Unrecognized task: %s" % (task,))

    def _default_exit(self, task):
        """
        Calls _assert_current() on the given task and then sets the
        composite returncode attribute if task.returncode != os.EX_OK.
        If the task failed then self._current_task will be set to None.
        Subclasses can use this as a generic task exit callback.

        @rtype: int
        @return: The task.returncode attribute.
        """
        self._assert_current(task)
        if task.returncode != os.EX_OK:
            self.returncode = task.returncode
            self.cancelled = task.cancelled
            self._current_task = None
        return task.returncode

    def _final_exit(self, task):
        """
        Assumes that task is the final task of this composite task.
        Calls _default_exit() and sets self.returncode to the task's
        returncode and sets self._current_task to None.
        """
        self._default_exit(task)
        self._current_task = None
        self.returncode = task.returncode
        return self.returncode

    def _default_final_exit(self, task):
        """
        This calls _final_exit() and then wait().

        Subclasses can use this as a generic final task exit callback.

        """
        self._final_exit(task)
        return self.wait()

    def _start_task(self, task, exit_handler):
        """
        Register exit handler for the given task, set it
        as self._current_task, and call task.start().

        Subclasses can use this as a generic way to start
        a task.

        """
        try:
            task.scheduler = self.scheduler
        except AttributeError:
            pass
        task.addExitListener(exit_handler)
        self._current_task = task
        task.start()

    def _task_queued(self, task):
        task.addStartListener(self._task_queued_start_handler)
        self._current_task = self._TASK_QUEUED

    def _task_queued_start_handler(self, task):
        self._current_task = task

    def _task_queued_wait(self):
        return (
            self._current_task is not self._TASK_QUEUED
            or self.cancelled
            or self.returncode is not None
        )
