#!/usr/bin/env python
# Copyright (C) 2020 Apple 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.

import argparse
import subprocess
import sys
import time


SUBMIT_DIAG_INFO = '/System/Library/CoreServices/SubmitDiagInfo'
WAIT_SECONDS = 3


def pid_for_name(process_name):
    process = subprocess.Popen(['/bin/ps', '-eo', 'pid,comm'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    stdout, _ = process.communicate()
    for line in stdout.splitlines():
        try:
            pid, candidate = line.strip().split(b' ', 1)
            if candidate == process_name:
                return int(pid)
        except ValueError:
            pass
    return None


def cpu_percentage(pid):
    top_output = subprocess.check_output(['/usr/bin/top', '-pid', str(pid), '-stats', 'cpu', '-l', '2'])
    try:
        return float(top_output.splitlines()[-1])
    except ValueError:
        return 0


def main():
    parser = argparse.ArgumentParser(description='Wait for crash log reporting to quiesce')
    parser.add_argument(
        '-t', '--timeout',
        help='Seconds to wait for process to quiesce.',
        type=int, default=0,
    )
    args = parser.parse_args()
    deadline = (time.time() + args.timeout) if args.timeout else None

    if sys.platform != 'darwin':
        print("No crash reporting available for platform '{}'".format(sys.platform))
        return 0

    pid = pid_for_name(SUBMIT_DIAG_INFO)
    if not pid:
        print('Failed to find any running process for {}'.format(SUBMIT_DIAG_INFO))
        return 0
    print('Found {} running with PID {}'.format(SUBMIT_DIAG_INFO, pid))

    print('Waiting for process {} to quiesce'.format(pid))
    while not deadline or deadline > time.time():
        if cpu_percentage(pid) <= 5:
            print('Process {} has quiesced'.format(pid))
            return 0
        time.sleep(WAIT_SECONDS)

    print('Timed out waiting for {} to quiesce, continue'.format(pid))
    return 0


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