#!/usr/bin/python

#----------------------------------------------------------------------
# This module will enable GDB remote packet logging when the
# 'start_gdb_log' command is called with a filename to log to. When the
# 'stop_gdb_log' command is called, it will disable the logging and
# print out statistics about how long commands took to execute and also
# will primnt ou
# Be sure to add the python path that points to the LLDB shared library.
#
# To use this in the embedded python interpreter using "lldb" just
# import it with the full path using the "command script import"
# command. This can be done from the LLDB command line:
#   (lldb) command script import /path/to/gdbremote.py
# Or it can be added to your ~/.lldbinit file so this module is always
# available.
#----------------------------------------------------------------------

import commands
import optparse
import os
import shlex
import re
import tempfile


def start_gdb_log(debugger, command, result, dict):
    '''Start logging GDB remote packets by enabling logging with timestamps and
    thread safe logging. Follow a call to this function with a call to "stop_gdb_log"
    in order to dump out the commands.'''
    global log_file
    if log_file:
        result.PutCString(
            'error: logging is already in progress with file "%s"',
            log_file)
    else:
        args_len = len(args)
        if args_len == 0:
            log_file = tempfile.mktemp()
        elif len(args) == 1:
            log_file = args[0]

        if log_file:
            debugger.HandleCommand(
                'log enable --threadsafe --timestamp --file "%s" gdb-remote packets' %
                log_file)
            result.PutCString(
                "GDB packet logging enable with log file '%s'\nUse the 'stop_gdb_log' command to stop logging and show packet statistics." %
                log_file)
            return

        result.PutCString('error: invalid log file path')
    result.PutCString(usage)


def parse_time_log(debugger, command, result, dict):
    # Any commands whose names might be followed by more valid C identifier
    # characters must be listed here
    command_args = shlex.split(command)
    parse_time_log_args(command_args)


def parse_time_log_args(command_args):
    usage = "usage: parse_time_log [options] [<LOGFILEPATH>]"
    description = '''Parse a log file that contains timestamps and convert the timestamps to delta times between log lines.'''
    parser = optparse.OptionParser(
        description=description,
        prog='parse_time_log',
        usage=usage)
    parser.add_option(
        '-v',
        '--verbose',
        action='store_true',
        dest='verbose',
        help='display verbose debug info',
        default=False)
    try:
        (options, args) = parser.parse_args(command_args)
    except:
        return
    for log_file in args:
        parse_log_file(log_file, options)


def parse_log_file(file, options):
    '''Parse a log file that was contains timestamps. These logs are typically
    generated using:
    (lldb) log enable --threadsafe --timestamp --file <FILE> ....

    This log file will contain timestamps and this function will then normalize
    those packets to be relative to the first value timestamp that is found and
    show delta times between log lines and also keep track of how long it takes
    for GDB remote commands to make a send/receive round trip. This can be
    handy when trying to figure out why some operation in the debugger is taking
    a long time during a preset set of debugger commands.'''

    print '#----------------------------------------------------------------------'
    print "# Log file: '%s'" % file
    print '#----------------------------------------------------------------------'

    timestamp_regex = re.compile('(\s*)([1-9][0-9]+\.[0-9]+)([^0-9].*)$')

    base_time = 0.0
    last_time = 0.0
    file = open(file)
    lines = file.read().splitlines()
    for line in lines:
        match = timestamp_regex.match(line)
        if match:
            curr_time = float(match.group(2))
            delta = 0.0
            if base_time:
                delta = curr_time - last_time
            else:
                base_time = curr_time

            print '%s%.6f %+.6f%s' % (match.group(1), curr_time - base_time, delta, match.group(3))
            last_time = curr_time
        else:
            print line


if __name__ == '__main__':
    import sys
    parse_time_log_args(sys.argv[1:])

else:
    import lldb
    if lldb.debugger:
        # This initializer is being run from LLDB in the embedded command interpreter
        # Add any commands contained in this module to LLDB
        lldb.debugger.HandleCommand(
            'command script add -f delta.parse_time_log parse_time_log')
        print 'The "parse_time_log" command is now installed and ready for use, type "parse_time_log --help" for more information'
