#
# Copyright BitBake Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#

import logging
import signal
import subprocess
import errno
import select
import bb

logger = logging.getLogger('BitBake.Process')

def subprocess_setup():
    # Python installs a SIGPIPE handler by default. This is usually not what
    # non-Python subprocesses expect.
    signal.signal(signal.SIGPIPE, signal.SIG_DFL)

class CmdError(RuntimeError):
    def __init__(self, command, msg=None):
        self.command = command
        self.msg = msg

    def __str__(self):
        if not isinstance(self.command, str):
            cmd = subprocess.list2cmdline(self.command)
        else:
            cmd = self.command

        msg = "Execution of '%s' failed" % cmd
        if self.msg:
            msg += ': %s' % self.msg
        return msg

class NotFoundError(CmdError):
    def __str__(self):
        return CmdError.__str__(self) + ": command not found"

class ExecutionError(CmdError):
    def __init__(self, command, exitcode, stdout = None, stderr = None):
        CmdError.__init__(self, command)
        self.exitcode = exitcode
        self.stdout = stdout
        self.stderr = stderr
        self.extra_message = None

    def __str__(self):
        message = ""
        if self.stderr:
            message += self.stderr
        if self.stdout:
            message += self.stdout
        if message:
            message = ":\n" + message
        return (CmdError.__str__(self) +
                " with exit code %s" % self.exitcode + message + (self.extra_message or ""))

class Popen(subprocess.Popen):
    defaults = {
        "close_fds": True,
        "preexec_fn": subprocess_setup,
        "stdout": subprocess.PIPE,
        "stderr": subprocess.PIPE,
        "stdin": subprocess.PIPE,
        "shell": False,
    }

    def __init__(self, *args, **kwargs):
        options = dict(self.defaults)
        options.update(kwargs)
        subprocess.Popen.__init__(self, *args, **options)

def _logged_communicate(pipe, log, input, extrafiles):
    if pipe.stdin:
        if input is not None:
            pipe.stdin.write(input)
        pipe.stdin.close()

    outdata, errdata = [], []
    rin = []

    if pipe.stdout is not None:
        bb.utils.nonblockingfd(pipe.stdout.fileno())
        rin.append(pipe.stdout)
    if pipe.stderr is not None:
        bb.utils.nonblockingfd(pipe.stderr.fileno())
        rin.append(pipe.stderr)
    for fobj, _ in extrafiles:
        bb.utils.nonblockingfd(fobj.fileno())
        rin.append(fobj)

    def readextras(selected):
        for fobj, func in extrafiles:
            if fobj in selected:
                try:
                    data = fobj.read()
                except IOError as err:
                    if err.errno == errno.EAGAIN or err.errno == errno.EWOULDBLOCK:
                        data = None
                if data is not None:
                    func(data)

    def read_all_pipes(log, rin, outdata, errdata):
        rlist = rin
        stdoutbuf = b""
        stderrbuf = b""

        try:
            r,w,e = select.select (rlist, [], [], 1)
        except OSError as e:
            if e.errno != errno.EINTR:
                raise

        readextras(r)

        if pipe.stdout in r:
            data = stdoutbuf + pipe.stdout.read()
            if data is not None and len(data) > 0:
                try:
                    data = data.decode("utf-8")
                    outdata.append(data)
                    log.write(data)
                    log.flush()
                    stdoutbuf = b""
                except UnicodeDecodeError:
                    stdoutbuf = data

        if pipe.stderr in r:
            data = stderrbuf + pipe.stderr.read()
            if data is not None and len(data) > 0:
                try:
                    data = data.decode("utf-8")
                    errdata.append(data)
                    log.write(data)
                    log.flush()
                    stderrbuf = b""
                except UnicodeDecodeError:
                    stderrbuf = data

    try:
        # Read all pipes while the process is open
        while pipe.poll() is None:
            read_all_pipes(log, rin, outdata, errdata)

        # Process closed, drain all pipes...
        read_all_pipes(log, rin, outdata, errdata)
    finally:
        log.flush()

    if pipe.stdout is not None:
        pipe.stdout.close()
    if pipe.stderr is not None:
        pipe.stderr.close()
    return ''.join(outdata), ''.join(errdata)

def run(cmd, input=None, log=None, extrafiles=None, **options):
    """Convenience function to run a command and return its output, raising an
    exception when the command fails"""

    if not extrafiles:
        extrafiles = []

    if isinstance(cmd, str) and not "shell" in options:
        options["shell"] = True

    try:
        pipe = Popen(cmd, **options)
    except OSError as exc:
        if exc.errno == 2:
            raise NotFoundError(cmd)
        else:
            raise CmdError(cmd, exc)

    if log:
        stdout, stderr = _logged_communicate(pipe, log, input, extrafiles)
    else:
        stdout, stderr = pipe.communicate(input)
        if not stdout is None:
            stdout = stdout.decode("utf-8")
        if not stderr is None:
            stderr = stderr.decode("utf-8")

    if pipe.returncode != 0:
        if log:
            # Don't duplicate the output in the exception if logging it
            raise ExecutionError(cmd, pipe.returncode, None, None)
        raise ExecutionError(cmd, pipe.returncode, stdout, stderr)
    return stdout, stderr
