#!/usr/bin/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
#----------------------------------------------------------------------

import commands
import optparse
import os
import platform
import re
import resource
import sys
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 = commands.getoutput("xcode-select --print-path")
        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()),
                            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))
                            
                            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 = commands.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)
