#!/usr/bin/env python3
#
# 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',
        'dart': 'dart.exe',
        'dart_precompiled_runtime': 'dart_precompiled_runtime.exe',
        'firefox': 'firefox.exe',
        'gen_snapshot': 'gen_snapshot.exe',
        'git': 'git.exe',
        'iexplore': 'iexplore.exe',
        'vctip': 'vctip.exe',
        'mspdbsrv': 'mspdbsrv.exe',
    },
    'linux': {
        'chrome': 'chrome',
        'dart': 'dart',
        'dart_precompiled_runtime': 'dart_precompiled_runtime',
        'firefox': 'firefox',
        'gen_snapshot': 'gen_snapshot',
        'flutter_tester': 'flutter_tester',
        'git': 'git',
    },
    'macos': {
        'chrome': 'Chrome',
        'chrome_helper': 'Chrome Helper',
        'dart': 'dart',
        'dart_precompiled_runtime': 'dart_precompiled_runtime',
        'firefox': 'firefox',
        'gen_snapshot': 'gen_snapshot',
        'git': 'git',
        'safari': 'Safari',
    }
}

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]')
    true_or_false = ['True', 'False']
    parser.add_option(
        "--kill_dart",
        default='True',
        type='choice',
        choices=true_or_false,
        help="Kill all dart processes")
    parser.add_option(
        "--kill_vc",
        default='True',
        type='choice',
        choices=true_or_false,
        help="Kill all git processes")
    parser.add_option(
        "--kill_vsbuild",
        default='False',
        type='choice',
        choices=true_or_false,
        help="Kill all visual studio build related processes")
    parser.add_option(
        "--kill_browsers",
        default='False',
        type='choice',
        choices=true_or_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,
                         universal_newlines=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,
                         universal_newlines=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,
                             universal_newlines=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,
                         universal_newlines=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,
                         universal_newlines=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')
    return status


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


def KillVSBuild():
    status = Kill('vctip')
    status += Kill('mspdbsrv')
    return status


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


def Main():
    options = GetOptions()
    status = 0
    if options.kill_dart == 'True':
        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 == 'True':
        status += KillVCSystems()
    if options.kill_vsbuild == 'True' and os_name == 'win32':
        status += KillVSBuild()
    if options.kill_browsers == 'True':
        status += KillBrowsers()
    return status


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