#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License
#

# Extends the subprocess module to use runtime checkers, and report stderr output.

import os
import re
import subprocess
import tempfile
from subprocess import PIPE


def in_path(name):
    """Look for name in the PATH"""
    for path in os.environ["PATH"].split(os.pathsep):
        f = os.path.join(path, name)
        if os.path.isfile(f) and os.access(f, os.X_OK):
            return f


class TestProcessError(Exception):
    def __init__(self, proc, what, output=None):
        self.output = output
        sep = "\n%s stderr(%s) %s\n" % ("_" * 32, proc.pid, "_" * 32)
        error = sep + proc.error + sep if proc.error else ""
        super(TestProcessError, self).__init__("%s pid=%s exit=%s: %s%s" % (
            proc.cmd, proc.pid, proc.returncode, what, error))


class Popen(subprocess.Popen):
    """
    Add TEST_EXE_PREFIX to the command, check stderr for runtime checker output.
    In a 'with' statement it runs check_wait() on exit from the block, or
    check_kill() if initialized with kill_me=True
    """

    def __init__(self, *args, **kwargs):
        """
        Takes all args and kwargs of subprocess.Popen except stdout, stderr, universal_newlines
        kill_me=True runs check_kill() in __exit__() instead of check_wait()
        """
        self.on_exit = self.check_kill if kwargs.pop('kill_me', False) else self.check_wait
        self.errfile = tempfile.NamedTemporaryFile(delete=False)
        kwargs.update({'universal_newlines': True, 'stdout': PIPE, 'stderr': self.errfile})
        prefix = os.environ.get("TEST_EXE_PREFIX")
        if prefix:
            args = [prefix.split() + args[0]] + list(args[1:])
        self.cmd = args[0]
        super(Popen, self).__init__(*args, **kwargs)

    def check_wait(self):
        if self.wait() or self.error:
            raise TestProcessError(self, "check_wait")

    def communicate(self, *args, **kwargs):
        result = super(Popen, self).communicate(*args, **kwargs)
        if self.returncode or self.error:
            raise TestProcessError(self, "check_communicate", result[0])
        return result

    def check_kill(self):
        """Raise if process has already exited, kill and raise if self.error is not empty"""
        if self.poll() is None:
            self.kill()
            self.wait()
            self.stdout.close()     # Doesn't get closed if killed
            if self.error:
                raise TestProcessError(self, "check_kill found error output")
        else:
            raise TestProcessError(self, "check_kill process not running")

    def expect(self, pattern):
        line = self.stdout.readline()
        match = re.search(pattern, line)
        if not match:
            raise TestProcessError(self, "can't find '%s' in '%s'" % (pattern, line))
        return match

    @property
    def error(self):
        """Return stderr as string, may only be used after process has terminated."""
        assert(self.poll is not None)
        if not hasattr(self, "_error"):
            self.errfile.close()  # Not auto-deleted
            with open(self.errfile.name) as f:  # Re-open to read
                self._error = f.read().strip()
            os.unlink(self.errfile.name)
        return self._error

    def __enter__(self):
        return self

    def __exit__(self, *args):
        self.on_exit()


def check_output(*args, **kwargs):
    return Popen(*args, **kwargs).communicate()[0]


class Server(Popen):
    """A process that prints 'listening on <port>' to stdout"""

    def __init__(self, *args, **kwargs):
        super(Server, self).__init__(*args, **kwargs)
        self.port = self.expect("listening on ([0-9]+)$").group(1)
