#!/usr/bin/env python3
# Copyright (C) 2010 Apple Inc.  All rights reserved.
# Copyright (C) 2011 Google Inc.  All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from __future__ import print_function
import os, sys
import getpass
import re
import subprocess

def listAllWebKitPrograms(builddir_bin):
    foundWebKitPrograms = []
    for root, dirs, files in os.walk(builddir_bin):
        for file in files:
            if os.access(os.path.join(root, file), os.X_OK):
                foundWebKitPrograms.append(file)
    return foundWebKitPrograms

def removeOrphanShmSegments():
    # When Apache2 is not gracefully shut down, it may leave orphaned shared memory segments
    # that could cause following server instances to abort on startup.
    try:
        username = getpass.getuser()
        segments = orphanedShmSegmentsByUser(username)
        for s in segments:
            subprocess.check_call(["ipcrm", "-m", s])
    except Exception as e:
        print("Error removing orphaned shared memory segments: {}".format(e), file=sys.stderr)

def orphanedShmSegmentsByUser(username):
    ret = []
    output = subprocess.check_output(["ipcs", "-m"])
    if type(output) == bytes:
        output = output.decode('utf-8', errors='strict')
    lines = output.split('\n')
    if len(lines) < 3:
        return []

    headers = [header.strip() for header in lines[2].split()]
    wanted_headers = ['nattch', 'owner', 'shmid']

    if any(h not in headers for h in wanted_headers):
        raise RuntimeError("Failed to find required nattch, owner and shmid cols in ipcs output")
    nattch_idx = headers.index('nattch')
    owner_idx = headers.index('owner')
    shmid_idx = headers.index('shmid')

    for line in lines[3:]:
        line = line.strip()
        tokens = [x.strip() for x in line.split()]
        try:
            if tokens[nattch_idx] == '0' and tokens[owner_idx] == username:
                ret.append(tokens[shmid_idx])
        except IndexError:
            continue
    return ret

def main(user=None):
    tasksToKillWin = [
        "cl.exe",
        "devenv.com",
        "devenv.exe",
        "DumpRenderTree.exe",
        "DumpRenderTree_debug.exe",
        "httpd.exe",
        "imagediff.exe",
        "imagediff_debug.exe",
        "jsc.exe",
        "jsc_debug.exe",
        "LightTPD.exe",
        "link.exe",
        "midl.exe",
        "perl.exe",
        "Safari.exe",
        "svn.exe",
        "testapi.exe",
        "testapi_debug.exe",
        "VcBuildHelper.exe",
        "wdiff.exe",
        "WebKitNetworkProcess.exe",
        "WebKitNetworkProcess_debug.exe",
        "WebKitWebProcess.exe",
        "WebKitWebProcess_debug.exe",
        "WebKitTestRunner.exe",
        "WebKitTestRunner_debug.exe",
    ]

    tasksToKillMac = [
        "apache2",
        "cc1plus",
        "cc1objplus",
        "clang",
        r"clang\\+\\+",
        "gcc-4.2",
        "httpd",
        "i686-apple-darwin10-gcc-4.2.1",
        "ImageDiff",
        "jsc",
        "LayoutTestHelper",
        "make",
        "perl5.12",
        "perl5.16",
        "perl5.18",        
        "perl",
        "Problem Reporter",
        "ruby",
        "Safari Web Content",
        "Safari",
        "svn",
        "DumpRenderTree",
        "TestWebKitAPI Web Content",
        "TestWebKitAPI",
        "PluginProcess",
        "com.apple.WebKit.Plugin.64",
        "com.apple.WebKit.Plugin.32",
        "com.apple.WebKit.PluginProcess",
        "com.apple.WebKit.PluginProcess.Development"
        "WebKitTestRunner Web Content",
        "WebKitTestRunner",
        "WebProcess",
        "xcodebuild",
        # FIXME: Consider moving iOS-specific tasks to their own list.
        "Simulator.app",
    ]

    taskToKillUnix = [
        # System process that are executed as part of the build process
        "cc1plus",
        "ld.gold",
        "ld",
        "make",
        "cmake",
        "svn",
        # System process that are executed as part of the test steps
        "Xvfb",
        "gdb",
        "ruby",
        "apache2",
        "httpd",
        # WebKit related process names are automatically generated for GTK+/WPE/JSCOnly
    ]

    # This allows to specify on the environment of the bot a list of process that should be killed.
    tasksToKill = os.getenv("WEBKITBOT_TASKSTOKILL", "").split()
    if sys.platform == 'darwin':
        os.system("ps aux")
        for task in tasksToKill + tasksToKillMac:
            os.system("killall -9 -v -m " + task)
        # Shutdown any simulators
        if os.geteuid() == 0 and user:
            os.system("sudo -u {} xcrun simctl shutdown booted".format(user))
        else:
            os.system("xcrun simctl shutdown booted")
        # Kill all instances of python executing run-webkit-tests
        os.system("ps aux | grep -E '.+/Python3? .+(run_webkit_tests|run-webkit-tests|mod_pywebsocket)' | grep -v grep | awk '{print $2}' | xargs kill")
        # FIXME: <rdar://problem/81476546> Remove stale simulator temp files
        # Hard-code path because when run with 'sudo,' this script doesn't get the right tempfile location
        os.system('find /var/folders -name "Deleting-*" -maxdepth 4 -exec sudo rm -rf {} +')
    elif sys.platform == 'cygwin' or sys.platform == 'win32':
        for task in tasksToKill + tasksToKillWin:
            os.system("taskkill /t /f /im " + task)
    elif sys.platform.startswith('linux'):
        os.system("ps aux")
        builddir_bin = "WebKitBuild/Release/bin" if os.path.isdir("WebKitBuild/Release/bin") else "WebKitBuild/Debug/bin"
        for task in tasksToKill + taskToKillUnix + listAllWebKitPrograms(builddir_bin):
            os.system("killall -9 -v " + task)
        os.system("ps aux | grep -P '.+/python3? .+(run_webkit_tests|run-webkit-tests|mod_pywebsocket)' | grep -v grep | awk '{print $2}' | xargs -r kill")
        removeOrphanShmSegments()
    else:
        sys.exit()
        # FIXME: Should we return an exit code based on how the kills went?


if __name__ == '__main__':
    user = sys.argv[1] if len(sys.argv) > 1 else None
    sys.exit(main(user))
