# 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)]
