#!/usr/bin/env python

#----------------------------------------------------------------------
# Be sure to add the python path that points to the LLDB shared library.
# On MacOSX csh, tcsh:
#   setenv PYTHONPATH /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python
# On MacOSX sh, bash:
#   export PYTHONPATH=/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python
#----------------------------------------------------------------------

from __future__ import print_function

import optparse
import os
import platform
import re
import resource
import sys
import subprocess
import time
import types

#----------------------------------------------------------------------
# Code that auto imports LLDB
#----------------------------------------------------------------------
try:
    # Just try for LLDB in case PYTHONPATH is already correctly setup
    import lldb
except ImportError:
    lldb_python_dirs = list()
    # lldb is not in the PYTHONPATH, try some defaults for the current platform
    platform_system = platform.system()
    if platform_system == 'Darwin':
        # On Darwin, try the currently selected Xcode directory
        xcode_dir = subprocess.check_output("xcode-select --print-path", shell=True)
        if xcode_dir:
            lldb_python_dirs.append(
                os.path.realpath(
                    xcode_dir +
                    '/../SharedFrameworks/LLDB.framework/Resources/Python'))
            lldb_python_dirs.append(
                xcode_dir + '/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
        lldb_python_dirs.append(
            '/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
    success = False
    for lldb_python_dir in lldb_python_dirs:
        if os.path.exists(lldb_python_dir):
            if not (sys.path.__contains__(lldb_python_dir)):
                sys.path.append(lldb_python_dir)
                try:
                    import lldb
                except ImportError:
                    pass
                else:
                    print('imported lldb from: "%s"' % (lldb_python_dir))
                    success = True
                    break
    if not success:
        print("error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly")
        sys.exit(1)


class Timer:

    def __enter__(self):
        self.start = time.clock()
        return self

    def __exit__(self, *args):
        self.end = time.clock()
        self.interval = self.end - self.start


class Action(object):
    """Class that encapsulates actions to take when a thread stops for a reason."""

    def __init__(self, callback=None, callback_owner=None):
        self.callback = callback
        self.callback_owner = callback_owner

    def ThreadStopped(self, thread):
        assert False, "performance.Action.ThreadStopped(self, thread) must be overridden in a subclass"


class PlanCompleteAction (Action):

    def __init__(self, callback=None, callback_owner=None):
        Action.__init__(self, callback, callback_owner)

    def ThreadStopped(self, thread):
        if thread.GetStopReason() == lldb.eStopReasonPlanComplete:
            if self.callback:
                if self.callback_owner:
                    self.callback(self.callback_owner, thread)
                else:
                    self.callback(thread)
            return True
        return False


class BreakpointAction (Action):

    def __init__(
            self,
            callback=None,
            callback_owner=None,
            name=None,
            module=None,
            file=None,
            line=None,
            breakpoint=None):
        Action.__init__(self, callback, callback_owner)
        self.modules = lldb.SBFileSpecList()
        self.files = lldb.SBFileSpecList()
        self.breakpoints = list()
        # "module" can be a list or a string
        if breakpoint:
            self.breakpoints.append(breakpoint)
        else:
            if module:
                if isinstance(module, types.ListType):
                    for module_path in module:
                        self.modules.Append(
                            lldb.SBFileSpec(module_path, False))
                elif isinstance(module, types.StringTypes):
                    self.modules.Append(lldb.SBFileSpec(module, False))
            if name:
                # "file" can be a list or a string
                if file:
                    if isinstance(file, types.ListType):
                        self.files = lldb.SBFileSpecList()
                        for f in file:
                            self.files.Append(lldb.SBFileSpec(f, False))
                    elif isinstance(file, types.StringTypes):
                        self.files.Append(lldb.SBFileSpec(file, False))
                self.breakpoints.append(
                    self.target.BreakpointCreateByName(
                        name, self.modules, self.files))
            elif file and line:
                self.breakpoints.append(
                    self.target.BreakpointCreateByLocation(
                        file, line))

    def ThreadStopped(self, thread):
        if thread.GetStopReason() == lldb.eStopReasonBreakpoint:
            for bp in self.breakpoints:
                if bp.GetID() == thread.GetStopReasonDataAtIndex(0):
                    if self.callback:
                        if self.callback_owner:
                            self.callback(self.callback_owner, thread)
                        else:
                            self.callback(thread)
                    return True
        return False


class TestCase:
    """Class that aids in running performance tests."""

    def __init__(self):
        self.verbose = False
        self.debugger = lldb.SBDebugger.Create()
        self.target = None
        self.process = None
        self.thread = None
        self.launch_info = None
        self.done = False
        self.listener = self.debugger.GetListener()
        self.user_actions = list()
        self.builtin_actions = list()
        self.bp_id_to_dict = dict()

    def Setup(self, args):
        self.launch_info = lldb.SBLaunchInfo(args)

    def Run(self, args):
        assert False, "performance.TestCase.Run(self, args) must be subclassed"

    def Launch(self):
        if self.target:
            error = lldb.SBError()
            self.process = self.target.Launch(self.launch_info, error)
            if not error.Success():
                print("error: %s" % error.GetCString())
            if self.process:
                self.process.GetBroadcaster().AddListener(self.listener,
                                                          lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitInterrupt)
                return True
        return False

    def WaitForNextProcessEvent(self):
        event = None
        if self.process:
            while event is None:
                process_event = lldb.SBEvent()
                if self.listener.WaitForEvent(lldb.UINT32_MAX, process_event):
                    state = lldb.SBProcess.GetStateFromEvent(process_event)
                    if self.verbose:
                        print("event = %s" % (lldb.SBDebugger.StateAsCString(state)))
                    if lldb.SBProcess.GetRestartedFromEvent(process_event):
                        continue
                    if state == lldb.eStateInvalid or state == lldb.eStateDetached or state == lldb.eStateCrashed or state == lldb.eStateUnloaded or state == lldb.eStateExited:
                        event = process_event
                        self.done = True
                    elif state == lldb.eStateConnected or state == lldb.eStateAttaching or state == lldb.eStateLaunching or state == lldb.eStateRunning or state == lldb.eStateStepping or state == lldb.eStateSuspended:
                        continue
                    elif state == lldb.eStateStopped:
                        event = process_event
                        call_test_step = True
                        fatal = False
                        selected_thread = False
                        for thread in self.process:
                            frame = thread.GetFrameAtIndex(0)
                            select_thread = False

                            stop_reason = thread.GetStopReason()
                            if self.verbose:
                                print("tid = %#x pc = %#x " % (thread.GetThreadID(), frame.GetPC()), end=' ')
                            if stop_reason == lldb.eStopReasonNone:
                                if self.verbose:
                                    print("none")
                            elif stop_reason == lldb.eStopReasonTrace:
                                select_thread = True
                                if self.verbose:
                                    print("trace")
                            elif stop_reason == lldb.eStopReasonPlanComplete:
                                select_thread = True
                                if self.verbose:
                                    print("plan complete")
                            elif stop_reason == lldb.eStopReasonThreadExiting:
                                if self.verbose:
                                    print("thread exiting")
                            elif stop_reason == lldb.eStopReasonExec:
                                if self.verbose:
                                    print("exec")
                            elif stop_reason == lldb.eStopReasonInvalid:
                                if self.verbose:
                                    print("invalid")
                            elif stop_reason == lldb.eStopReasonException:
                                select_thread = True
                                if self.verbose:
                                    print("exception")
                                fatal = True
                            elif stop_reason == lldb.eStopReasonBreakpoint:
                                select_thread = True
                                bp_id = thread.GetStopReasonDataAtIndex(0)
                                bp_loc_id = thread.GetStopReasonDataAtIndex(1)
                                if self.verbose:
                                    print("breakpoint id = %d.%d" % (bp_id, bp_loc_id))
                            elif stop_reason == lldb.eStopReasonWatchpoint:
                                select_thread = True
                                if self.verbose:
                                    print("watchpoint id = %d" % (thread.GetStopReasonDataAtIndex(0)))
                            elif stop_reason == lldb.eStopReasonSignal:
                                select_thread = True
                                if self.verbose:
                                    print("signal %d" % (thread.GetStopReasonDataAtIndex(0)))
                            elif stop_reason == lldb.eStopReasonFork:
                                if self.verbose:
                                    print("fork pid = %d" % (thread.GetStopReasonDataAtIndex(0)))
                            elif stop_reason == lldb.eStopReasonVFork:
                                if self.verbose:
                                    print("vfork pid = %d" % (thread.GetStopReasonDataAtIndex(0)))
                            elif stop_reason == lldb.eStopReasonVForkDone:
                                if self.verbose:
                                    print("vfork done")

                            if select_thread and not selected_thread:
                                self.thread = thread
                                selected_thread = self.process.SetSelectedThread(
                                    thread)

                            for action in self.user_actions:
                                action.ThreadStopped(thread)

                        if fatal:
                            # if self.verbose:
                            #     Xcode.RunCommand(self.debugger,"bt all",true)
                            sys.exit(1)
        return event


class Measurement:
    '''A class that encapsulates a measurement'''

    def __init__(self):
        object.__init__(self)

    def Measure(self):
        assert False, "performance.Measurement.Measure() must be subclassed"


class MemoryMeasurement(Measurement):
    '''A class that can measure memory statistics for a process.'''

    def __init__(self, pid):
        Measurement.__init__(self)
        self.pid = pid
        self.stats = [
            "rprvt",
            "rshrd",
            "rsize",
            "vsize",
            "vprvt",
            "kprvt",
            "kshrd",
            "faults",
            "cow",
            "pageins"]
        self.command = "top -l 1 -pid %u -stats %s" % (
            self.pid, ",".join(self.stats))
        self.value = dict()

    def Measure(self):
        output = subprocess.getoutput(self.command).split("\n")[-1]
        values = re.split('[-+\s]+', output)
        for (idx, stat) in enumerate(values):
            multiplier = 1
            if stat:
                if stat[-1] == 'K':
                    multiplier = 1024
                    stat = stat[:-1]
                elif stat[-1] == 'M':
                    multiplier = 1024 * 1024
                    stat = stat[:-1]
                elif stat[-1] == 'G':
                    multiplier = 1024 * 1024 * 1024
                elif stat[-1] == 'T':
                    multiplier = 1024 * 1024 * 1024 * 1024
                    stat = stat[:-1]
                self.value[self.stats[idx]] = int(stat) * multiplier

    def __str__(self):
        '''Dump the MemoryMeasurement current value'''
        s = ''
        for key in self.value.keys():
            if s:
                s += "\n"
            s += "%8s = %s" % (key, self.value[key])
        return s


class TesterTestCase(TestCase):

    def __init__(self):
        TestCase.__init__(self)
        self.verbose = True
        self.num_steps = 5

    def BreakpointHit(self, thread):
        bp_id = thread.GetStopReasonDataAtIndex(0)
        loc_id = thread.GetStopReasonDataAtIndex(1)
        print("Breakpoint %i.%i hit: %s" % (bp_id, loc_id, thread.process.target.FindBreakpointByID(bp_id)))
        thread.StepOver()

    def PlanComplete(self, thread):
        if self.num_steps > 0:
            thread.StepOver()
            self.num_steps = self.num_steps - 1
        else:
            thread.process.Kill()

    def Run(self, args):
        self.Setup(args)
        with Timer() as total_time:
            self.target = self.debugger.CreateTarget(args[0])
            if self.target:
                with Timer() as breakpoint_timer:
                    bp = self.target.BreakpointCreateByName("main")
                print(
                    'Breakpoint time = %.03f sec.' %
                    breakpoint_timer.interval)

                self.user_actions.append(
                    BreakpointAction(
                        breakpoint=bp,
                        callback=TesterTestCase.BreakpointHit,
                        callback_owner=self))
                self.user_actions.append(
                    PlanCompleteAction(
                        callback=TesterTestCase.PlanComplete,
                        callback_owner=self))

                if self.Launch():
                    while not self.done:
                        self.WaitForNextProcessEvent()
                else:
                    print("error: failed to launch process")
            else:
                print("error: failed to create target with '%s'" % (args[0]))
        print('Total time = %.03f sec.' % total_time.interval)


if __name__ == '__main__':
    lldb.SBDebugger.Initialize()
    test = TesterTestCase()
    test.Run(sys.argv[1:])
    mem = MemoryMeasurement(os.getpid())
    mem.Measure()
    print(str(mem))
    lldb.SBDebugger.Terminate()
    # print "sleeeping for 100 seconds"
    # time.sleep(100)
