#!/usr/bin/python

# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

""" Return the time difference between two logfile entries
"""

import logging
import optparse
import os
import re
import sys
import time

logger = logging.getLogger('log_time_diff')
handler = logging.StreamHandler(file('/dev/stderr', 'w'))
formatter = logging.Formatter('\tlog_time_diff: %(levelname)s\t%(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)


class StampParser(object):
    saved_msgs = '/var/tmp/messages.autotest_start'
    def __init__(self, from_str, to_str, start = None):
        self.from_re = re.compile(from_str)
        self.to_re = re.compile(to_str)
        self.start_line = None
        self.end_line = None
        if start:
            self.start = self.syslog_to_float(start)
        else:
            if os.path.exists(self.saved_msgs):
                for line in file(self.saved_msgs):
                    pass
                self.start = self.syslog_to_float(line.split(' ')[0])

    def parse_file(self, filename):
        for line in file(filename):
            if self.from_re.search(line):
                self.end_line = None
                self.start_line = line
            if self.to_re.search(line):
                self.end_line = line

    def syslog_to_float(self, syslog_time):
        # Lines end up like 2011-05-13T07:38:05.238129-07:00 ...
        date, sep, fraction = syslog_time.partition('.')
        int_time = time.mktime(time.strptime(date, '%Y-%m-%dT%H:%M:%S'))
        return float('%d.%s' % (int_time, fraction.split('-')[0]))

    def results(self):
        if not self.start_line or not self.end_line:
            logger.error('Could not find strings in file')
            return '-'

        logger.debug('Start line: %s', self.start_line)
        logger.debug('End line: %s', self.end_line)

        syslog_from = self.start_line.split(' ')[0]
        syslog_from_time = self.syslog_to_float(syslog_from)
        if self.start and syslog_from_time < self.start:
            logger.error('Search string only appears before start time!')
            return '-'

        from_match = re.search('kernel:\s*\[\s*([0-9.]*)', self.start_line)
        to_match = re.search('kernel:\s*\[\s*([0-9.]*)', self.end_line)
        if from_match and to_match:
            # Lines end up like <syslog time> host kernel: [1307112.080338] ...
            logger.info('Using kernel timestamp %s %s' %
                         (from_match.group(1), to_match.group(1)))
            from_time = float(from_match.group(1))
            to_time = float(to_match.group(1))
        else:
            syslog_to = self.end_line.split(' ')[0]
            logger.info('Using syslog timestamp %s %s' %
                         (syslog_from, syslog_to))
            from_time = syslog_from_time
            to_time = self.syslog_to_float(syslog_to)
        return (to_time - from_time)


def main(argv):
    parser = optparse.OptionParser('Usage: %prog [options...]')
    parser.add_option('--from', dest='from_str',
                      help='First regexp to search for')
    parser.add_option('--to', dest='to_str',
                      help='Second regexp to search for')
    parser.add_option('--file', dest='file', default='/var/log/messages',
                      help='File to search for regexps in')
    parser.add_option('--no-rotate', dest='no_rotate', action='store_true',
                      help='Do not search in file.1 for the same expression')
    parser.add_option('--start', dest='start',
                      help='Do not accept events that start before this time')
    parser.add_option('--debug', dest='debug', action='store_true',
                      help='Show extra verbose messages')
    (options, args) = parser.parse_args(argv[1:])

    if not options.from_str or not options.to_str:
        parser.error('Required arguments: --from=<from_re> --to=<to_re>')


    if options.debug:
        logger.setLevel(logging.DEBUG)
    else:
        logger.setLevel(logging.INFO)

    parser = StampParser(options.from_str, options.to_str, options.start)

    # If file rotation is enabled, try to parse previous file
    if not options.no_rotate:
        rotate_file = '%s.1' % options.file
        if os.path.exists(rotate_file):
            parser.parse_file(rotate_file)

    parser.parse_file(options.file)
    print parser.results()

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