#!/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': 'dart.exe',
    'iexplore': 'iexplore.exe',
    'firefox': 'firefox.exe',
    'git': 'git.exe',
    'svn': 'svn.exe',
    'fletch': 'fletch.exe',
    'fletch-vm': 'fletch-vm.exe',
  },
  'linux': {
    'chrome': 'chrome',
    'content_shell': 'content_shell',
    'dart': 'dart',
    'firefox': 'firefox.exe',
    'git': 'git',
    'svn': 'svn',
    'fletch': 'fletch',
    'fletch-vm': 'fletch-vm',
  },
  'macos': {
    'chrome': 'Chrome',
    'content_shell': 'Content Shell',
    'dart': 'dart',
    'firefox': 'firefox',
    'safari': 'Safari',
    'git': 'git',
    'svn': 'svn',
    'fletch': 'fletch',
    'fletch-vm': 'fletch-vm',
  }
}

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

def GetOptions():
  parser = optparse.OptionParser("usage: %prog [options]")
  parser.add_option("--kill_dart", default=True,
                    help="Kill all dart processes")
  parser.add_option("--kill_fletch", default=True,
                    help="Kill all fletch and fletch-vm 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 PrintPidInfo(pid):
  # 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)
  for line in lines:
    # wmic will output a bunch of empty strings, we ignore these
    if len(line) >= 1:
      print("Hanging process info:")
      print("  PID: %s" % pid)
      print("  Command line: %s" % line)


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):
  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)
    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('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")
  return status

def KillFletch():
  status = Kill("fletch")
  status += Kill("fletch-vm")
  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_fletch:
    status += KillFletch()
  if options.kill_vc:
    status += KillVCSystems()
  if options.kill_browsers:
    status += KillBrowsers()
  return status

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