#!/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 process. 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())
