# Copyright 2006-2008 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Shared process-related utility functions."""

from __future__ import print_function

import errno
import os
import subprocess
import sys

class CommandNotFound(Exception): pass


TASKKILL = os.path.join(os.environ['WINDIR'], 'system32', 'taskkill.exe')
TASKKILL_PROCESS_NOT_FOUND_ERR = 128
# On windows 2000 there is no taskkill.exe, we need to have pskill somewhere
# in the path.
PSKILL = 'pskill.exe'
PSKILL_PROCESS_NOT_FOUND_ERR = -1

def KillAll(executables):
  """Tries to kill all copies of each process in the processes list.  Returns
  an error if any running processes couldn't be killed.
  """
  result = 0
  if os.path.exists(TASKKILL):
    command = [TASKKILL, '/f', '/im']
    process_not_found_err = TASKKILL_PROCESS_NOT_FOUND_ERR
  else:
    command = [PSKILL, '/t']
    process_not_found_err = PSKILL_PROCESS_NOT_FOUND_ERR

  for name in executables:
    new_error = RunCommand(command + [name])
    # Ignore "process not found" error.
    if new_error != 0 and new_error != process_not_found_err:
      result = new_error
  return result

def RunCommandFull(command, verbose=True, collect_output=False,
                   print_output=True):
  """Runs the command list.

  Prints the given command (which should be a list of one or more strings).
  If specified, prints its stderr (and optionally stdout) to stdout,
  line-buffered, converting line endings to CRLF (see note below).  If
  specified, collects the output as a list of lines and returns it.  Waits
  for the command to terminate and returns its status.

  Args:
    command: the full command to run, as a list of one or more strings
    verbose: if True, combines all output (stdout and stderr) into stdout.
             Otherwise, prints only the command's stderr to stdout.
    collect_output: if True, collects the output of the command as a list of
                    lines and returns it
    print_output: if True, prints the output of the command

  Returns:
    A tuple consisting of the process's exit status and output.  If
    collect_output is False, the output will be [].

  Raises:
    CommandNotFound if the command executable could not be found.
  """
  print(
      '\n' + subprocess.list2cmdline(command).replace('\\', '/') + '\n',
      end=' ')

  if verbose:
    out = subprocess.PIPE
    err = subprocess.STDOUT
  else:
    out = file(os.devnull, 'w')
    err = subprocess.PIPE
  try:
    proc = subprocess.Popen(command, stdout=out, stderr=err, bufsize=1)
  except OSError, e:
    if e.errno == errno.ENOENT:
      raise CommandNotFound('Unable to find "%s"' % command[0])
    raise

  output = []

  if verbose:
    read_from = proc.stdout
  else:
    read_from = proc.stderr
  line = read_from.readline()
  while line:
    line = line.rstrip()

    if collect_output:
      output.append(line)

    if print_output:
      # Windows Python converts \n to \r\n automatically whenever it
      # encounters it written to a text file (including stdout).  The only
      # way around it is to write to a binary file, which isn't feasible for
      # stdout. So we end up with \r\n here even though we explicitly write
      # \n.  (We could write \r instead, which doesn't get converted to \r\n,
      # but that's probably more troublesome for people trying to read the
      # files.)
      print(line + '\n', end=' ')

      # Python on windows writes the buffer only when it reaches 4k. This is
      # not fast enough for all purposes.
      sys.stdout.flush()
    line = read_from.readline()

  # Make sure the process terminates.
  proc.wait()

  if not verbose:
    out.close()
  return (proc.returncode, output)

def RunCommand(command, verbose=True):
  """Runs the command list, printing its output and returning its exit status.

  Prints the given command (which should be a list of one or more strings),
  then runs it and prints its stderr (and optionally stdout) to stdout,
  line-buffered, converting line endings to CRLF.  Waits for the command to
  terminate and returns its status.

  Args:
    command: the full command to run, as a list of one or more strings
    verbose: if True, combines all output (stdout and stderr) into stdout.
             Otherwise, prints only the command's stderr to stdout.

  Returns:
    The process's exit status.

  Raises:
    CommandNotFound if the command executable could not be found.
  """
  return RunCommandFull(command, verbose)[0]

def RunCommandsInParallel(commands, verbose=True, collect_output=False,
                          print_output=True):
  """Runs a list of commands in parallel, waits for all commands to terminate
  and returns their status. If specified, the ouput of commands can be
  returned and/or printed.

  Args:
    commands: the list of commands to run, each as a list of one or more
              strings.
    verbose: if True, combines stdout and stderr into stdout.
             Otherwise, prints only the command's stderr to stdout.
    collect_output: if True, collects the output of the each command as a list
                    of lines and returns it.
    print_output: if True, prints the output of each command.

  Returns:
    A list of tuples consisting of each command's exit status and output.  If
    collect_output is False, the output will be [].

  Raises:
    CommandNotFound if any of the command executables could not be found.
  """

  command_num = len(commands)
  outputs = [[] for i in xrange(command_num)]
  procs = [None for i in xrange(command_num)]
  eofs = [False for i in xrange(command_num)]

  for command in commands:
    print(
        '\n' + subprocess.list2cmdline(command).replace('\\', '/') + '\n',
        end=' ')

  if verbose:
    out = subprocess.PIPE
    err = subprocess.STDOUT
  else:
    out = file(os.devnull, 'w')
    err = subprocess.PIPE

  for i in xrange(command_num):
    try:
      command = commands[i]
      procs[i] = subprocess.Popen(command, stdout=out, stderr=err, bufsize=1)
    except OSError, e:
      if e.errno == errno.ENOENT:
        raise CommandNotFound('Unable to find "%s"' % command[0])
      raise
      # We could consider terminating the processes already started.
      # But Popen.kill() is only available in version 2.6.
      # For now the clean up is done by KillAll.

  while True:
    eof_all = True
    for i in xrange(command_num):
      if eofs[i]:
        continue
      if verbose:
        read_from = procs[i].stdout
      else:
        read_from = procs[i].stderr
      line = read_from.readline()
      if line:
        eof_all = False
        line = line.rstrip()
        outputs[i].append(line)
        if print_output:
          # Windows Python converts \n to \r\n automatically whenever it
          # encounters it written to a text file (including stdout).  The only
          # way around it is to write to a binary file, which isn't feasible
          # for stdout. So we end up with \r\n here even though we explicitly
          # write \n.  (We could write \r instead, which doesn't get converted
          # to \r\n, but that's probably more troublesome for people trying to
          # read the files.)
          print(line + '\n', end=' ')
      else:
        eofs[i] = True
    if eof_all:
      break

  # Make sure the process terminates.
  for i in xrange(command_num):
    procs[i].wait()

  if not verbose:
    out.close()

  return [(procs[i].returncode, outputs[i]) for i in xrange(command_num)]
