#! /usr/bin/python
# Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Written by Colin Watson for Canonical Ltd.

from __future__ import print_function

import os
import subprocess
import signal
import sys


class SubprocessException(RuntimeError):
    pass


def subprocess_setup():
    # Python installs a SIGPIPE handler by default. This is bad for
    # non-Python subprocesses, which need SIGPIPE set to the default action
    # or else they won't notice if the debconffilter dies.
    signal.signal(signal.SIGPIPE, signal.SIG_DFL)


def spawn(args, **kwargs):
    """Spawn a subprocess. Raise SubprocessException if it fails."""
    print(' '.join(args))
    sys.stdout.flush()

    ret = subprocess.call(args, preexec_fn=subprocess_setup, **kwargs)
    if ret != 0:
        raise SubprocessException(ret)


def spawn_root(args, **kwargs):
    """Spawn a subprocess as root. Raise SubprocessException if it fails."""
    # TODO hardcoding of root escalation method
    if os.getuid() != 0:
        new_args = ['sudo']
        new_args.extend(args)
        args = new_args
    spawn(args, **kwargs)


def get_output(args, mayfail=False, **kwargs):
    """Get the output of a subprocess."""
    subp = subprocess.Popen(args, preexec_fn=subprocess_setup,
                            stdout=subprocess.PIPE, universal_newlines=True,
                            **kwargs)
    output = subp.communicate()[0]
    if subp.returncode != 0 and not mayfail:
        print(' '.join(args))
        raise SubprocessException(subp.returncode)
    return output


def get_output_root(args, mayfail=False, **kwargs):
    """Get the output of a subprocess, run as root. Raise
    SubprocessException if it fails."""
    # TODO hardcoding of root escalation method
    if os.getuid() != 0:
        new_args = ['sudo']
        new_args.extend(args)
        args = new_args
    return get_output(args, mayfail=mayfail, **kwargs)


def file_on_path(filename, searchpath):
    """Return true if file found on search path."""
    for path in searchpath.split(os.pathsep):
        if os.path.exists(os.path.join(path, filename)):
            return True
    return False
