#!/usr/bin/env python
#
# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
#

# A script to kill hanging processs. The tool will return non-zero if any
# process was actually found.
#

import optparse
import os
import signal
import subprocess
import sys

import utils


os_name = utils.GuessOS()

POSIX_INFO = 'ps -p %s -o args'

EXECUTABLE_NAMES = {
  'win32': {
    'chrome': 'chrome.exe',
    'content_shell': 'content_shell.exe',
    'dart_bootstrap': 'dart_bootstrap.exe',
    'dart': 'dart.exe',
    'dart_precompiled_runtime': 'dart_precompiled_runtime.exe',
    'firefox': 'firefox.exe',
    'gen_snapshot': 'gen_snapshot.exe',
    'git': 'git.exe',
    'iexplore': 'iexplore.exe',
    'svn': 'svn.exe',
  },
  'linux': {
    'chrome': 'chrome',
    'content_shell': 'content_shell',
    'dart_bootstrap': 'dart_bootstrap',
    'dart': 'dart',
    'dart_precompiled_runtime': 'dart_precompiled_runtime',
    'firefox': 'firefox',
    'gen_snapshot': 'gen_snapshot',
    'git': 'git',
    'svn': 'svn',
  },
  'macos': {
    'chrome': 'Chrome',
    'chrome_helper': 'Chrome Helper',
    'content_shell': 'Content Shell',
    'dart_bootstrap': 'dart_bootstrap',
    'dart': 'dart',
    'dart_precompiled_runtime': 'dart_precompiled_runtime',
    'firefox': 'firefox',
    'gen_snapshot': 'gen_snapshot',
    'git': 'git',
    'safari': 'Safari',
    'svn': 'svn',
  }
}

INFO_COMMAND = {
  'win32': 'wmic process where Processid=%s get CommandLine',
  'macos': POSIX_INFO,
  'linux': POSIX_INFO,
}

STACK_INFO_COMMAND = {
  'win32': None,
  'macos': '/usr/bin/sample %s 1 4000 -mayDie',
  'linux': '/usr/bin/eu-stack -p %s',
}

def GetOptions():
  parser = optparse.OptionParser("usage: %prog [options]")
  parser.add_option("--kill_dart", default=True,
                    help="Kill all dart processes")
  parser.add_option("--kill_vc", default=True,
                    help="Kill all git and svn processes")
  parser.add_option("--kill_browsers", default=False,
                     help="Kill all browser processes")
  (options, args) = parser.parse_args()
  return options


def GetPidsPosix(process_name):
  # This is to have only one posix command, on linux we could just do:
  # pidof process_name
  cmd = 'ps -e -o pid= -o comm='
  # Sample output:
  # 1 /sbin/launchd
  # 80943 /Applications/Safari.app/Contents/MacOS/Safari
  p = subprocess.Popen(cmd,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE,
                       shell=True)
  output, stderr = p.communicate()
  results = []
  lines = output.splitlines()
  for line in lines:
    split = line.split()
    # On mac this ps commands actually gives us the full path to non
    # system binaries.
    if len(split) >= 2 and " ".join(split[1:]).endswith(process_name):
      results.append(split[0])
  return results


def GetPidsWindows(process_name):
  cmd = 'tasklist /FI "IMAGENAME eq %s" /NH' % process_name
  # Sample output:
  # dart.exe    4356 Console            1      6,800 K
  p = subprocess.Popen(cmd,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE,
                       shell=True)
  output, stderr = p.communicate()
  results = []
  lines = output.splitlines()

  for line in lines:
    split = line.split()
    if len(split) > 2 and split[0] == process_name:
      results.append(split[1])
  return results

def GetPids(process_name):
  if os_name == "win32":
    return GetPidsWindows(process_name)
  else:
    return GetPidsPosix(process_name)

def PrintPidStackInfo(pid):
  command_pattern = STACK_INFO_COMMAND.get(os_name, False)
  if command_pattern:
    p = subprocess.Popen(command_pattern % pid,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE,
                         shell=True)
    stdout, stderr = p.communicate()
    stdout = stdout.splitlines()
    stderr = stderr.splitlines()

    print "  Stack:"
    for line in stdout:
      print "    %s" % line
    if stderr:
      print "  Stack (stderr):"
      for line in stderr:
        print "    %s" % line

def PrintPidInfo(pid, dump_stacks):
  # We assume that the list command will return lines in the format:
  # EXECUTABLE_PATH ARGS
  # There may be blank strings in the output
  p = subprocess.Popen(INFO_COMMAND[os_name] % pid,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE,
                       shell=True)
  output, stderr = p.communicate()
  lines = output.splitlines()

  # Pop the header
  lines.pop(0)

  print "Hanging process info:"
  print "  PID: %s" % pid
  for line in lines:
    # wmic will output a bunch of empty strings, we ignore these
    if line: print "  Command line: %s" % line

  if dump_stacks:
    PrintPidStackInfo(pid)

def KillPosix(pid):
  try:
    os.kill(int(pid), signal.SIGKILL)
  except:
    # Ignore this, the process is already dead from killing another process.
    pass

def KillWindows(pid):
  # os.kill is not available until python 2.7
  cmd = "taskkill /F /PID %s" % pid
  p = subprocess.Popen(cmd,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE,
                       shell=True)
  p.communicate()

def Kill(name, dump_stacks=False):
  if name not in EXECUTABLE_NAMES[os_name]:
    return 0
  print("***************** Killing %s *****************" % name)
  platform_name = EXECUTABLE_NAMES[os_name][name]
  pids = GetPids(platform_name)
  for pid in pids:
    PrintPidInfo(pid, dump_stacks)
    if os_name == "win32":
      KillWindows(pid)
    else:
      KillPosix(pid)
    print("Killed pid: %s" % pid)
  if len(pids) == 0:
    print("  No %s processes found." % name)
  return len(pids)

def KillBrowsers():
  status = Kill('firefox')
  # We don't give error on killing chrome. It happens quite often that the
  # browser controller fails in killing chrome, so we silently do it here.
  Kill('chrome')
  status += Kill('chrome_helper')
  status += Kill('iexplore')
  status += Kill('safari')
  status += Kill('content_shell')
  return status

def KillVCSystems():
  status = Kill('git')
  status += Kill('svn')
  return status

def KillDart():
  status = Kill("dart", dump_stacks=True)
  status += Kill("dart_bootstrap", dump_stacks=True)
  status += Kill("gen_snapshot", dump_stacks=True)
  status += Kill("dart_precompiled_runtime", dump_stacks=True)
  return status

def Main():
  options = GetOptions()
  status = 0
  if options.kill_dart:
    if os_name == "win32":
      # TODO(24086): Add result of KillDart into status once pub hang is fixed.
      KillDart()
    else:
      status += KillDart()
  if options.kill_vc:
    status += KillVCSystems()
  if options.kill_browsers:
    status += KillBrowsers()
  return status

if __name__ == '__main__':
  sys.exit(Main())
