# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

import fcntl

from portage import os
from _emerge.AbstractPollTask import AbstractPollTask


class PipeReader(AbstractPollTask):

    """
    Reads output from one or more files and saves it in memory,
    for retrieval via the getvalue() method. This is driven by
    the scheduler's poll() loop, so it runs entirely within the
    current process.
    """

    __slots__ = ("input_files",) + ("_read_data", "_use_array")

    def _start(self):
        self._read_data = []

        for f in self.input_files.values():
            fd = f if isinstance(f, int) else f.fileno()
            fcntl.fcntl(
                fd, fcntl.F_SETFL, fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK
            )

            if self._use_array:
                self.scheduler.add_reader(fd, self._array_output_handler, f)
            else:
                self.scheduler.add_reader(fd, self._output_handler, fd)

        self._registered = True

    def _cancel(self):
        self._unregister()
        if self.returncode is None:
            self.returncode = self._cancelled_returncode

    def getvalue(self):
        """Retrieve the entire contents"""
        return b"".join(self._read_data)

    def close(self):
        """Free the memory buffer."""
        self._read_data = None

    def _output_handler(self, fd):

        while True:
            data = self._read_buf(fd)
            if data is None:
                break
            if data:
                self._read_data.append(data)
            else:
                self._unregister()
                self.returncode = self.returncode or os.EX_OK
                self._async_wait()
                break

    def _array_output_handler(self, f):

        while True:
            data = self._read_array(f)
            if data is None:
                break
            if data:
                self._read_data.append(data)
            else:
                self._unregister()
                self.returncode = self.returncode or os.EX_OK
                self._async_wait()
                break

        return True

    def _unregister(self):
        """
        Unregister from the scheduler and close open files.
        """

        self._registered = False

        if self.input_files is not None:
            for f in self.input_files.values():
                if isinstance(f, int):
                    self.scheduler.remove_reader(f)
                    os.close(f)
                else:
                    self.scheduler.remove_reader(f.fileno())
                    f.close()
            self.input_files = None
