#!/usr/bin/env python

# Copyright 2013 IBM Corp.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import gzip
import pprint
import re
import sys

import six
import six.moves.urllib.request as urlreq


pp = pprint.PrettyPrinter()

NOVA_TIMESTAMP = r"\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\.\d\d\d"

NOVA_REGEX = r"(?P<timestamp>%s) (?P<pid>\d+ )?(?P<level>(ERROR|TRACE)) " \
    "(?P<module>[\w\.]+) (?P<msg>.*)" % (NOVA_TIMESTAMP)


class StackTrace(object):
    timestamp = None
    pid = None
    level = ""
    module = ""
    msg = ""

    def __init__(self, timestamp=None, pid=None, level="", module="",
                 msg=""):
        self.timestamp = timestamp
        self.pid = pid
        self.level = level
        self.module = module
        self.msg = msg

    def append(self, msg):
        self.msg = self.msg + msg

    def is_same(self, data):
        return (data['timestamp'] == self.timestamp and
                data['level'] == self.level)

    def not_none(self):
        return self.timestamp is not None

    def __str__(self):
        buff = "<%s %s %s>\n" % (self.timestamp, self.level, self.module)
        for line in self.msg.splitlines():
            buff = buff + line + "\n"
        return buff


def hunt_for_stacktrace(url):
    """Return TRACE or ERROR lines out of logs."""
    req = urlreq.Request(url)
    req.add_header('Accept-Encoding', 'gzip')
    page = urlreq.urlopen(req)
    buf = six.StringIO(page.read())
    f = gzip.GzipFile(fileobj=buf)
    content = f.read()

    traces = []
    trace = StackTrace()
    for line in content.splitlines():
        m = re.match(NOVA_REGEX, line)
        if m:
            data = m.groupdict()
            if trace.not_none() and trace.is_same(data):
                trace.append(data['msg'] + "\n")
            else:
                trace = StackTrace(
                    timestamp=data.get('timestamp'),
                    pid=data.get('pid'),
                    level=data.get('level'),
                    module=data.get('module'),
                    msg=data.get('msg'))

        else:
            if trace.not_none():
                traces.append(trace)
                trace = StackTrace()

    # once more at the end to pick up any stragglers
    if trace.not_none():
        traces.append(trace)

    return traces


def log_url(url, log):
    return "%s/%s" % (url, log)


def collect_logs(url):
    page = urlreq.urlopen(url)
    content = page.read()
    logs = re.findall('(screen-[\w-]+\.txt\.gz)</a>', content)
    return logs


def usage():
    print("""
Usage: find_stack_traces.py <logurl>

Hunts for stack traces in a devstack run. Must provide it a base log url
from a tempest devstack run. Should start with http and end with /logs/.

Returns a report listing stack traces out of the various files where
they are found.
""")
    sys.exit(0)


def print_stats(items, fname, verbose=False):
    errors = len(filter(lambda x: x.level == "ERROR", items))
    traces = len(filter(lambda x: x.level == "TRACE", items))
    print("%d ERRORS found in %s" % (errors, fname))
    print("%d TRACES found in %s" % (traces, fname))

    if verbose:
        for item in items:
            print(item)
        print("\n\n")


def main():
    if len(sys.argv) == 2:
        url = sys.argv[1]
        loglist = collect_logs(url)

        # probably wrong base url
        if not loglist:
            usage()

        for log in loglist:
            logurl = log_url(url, log)
            traces = hunt_for_stacktrace(logurl)

            if traces:
                print_stats(traces, log, verbose=True)

    else:
        usage()

if __name__ == '__main__':
    main()
