#!/usr/bin/env python3
#
# Copyright (C) 2015 The Android Open Source Project
#
# 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.
#

"""Simpleperf gui reporter: provide gui interface for simpleperf report command.

There are two ways to use gui reporter. One way is to pass it a report file
generated by simpleperf report command, and reporter will display it. The
other ways is to pass it any arguments you want to use when calling
simpleperf report command. The reporter will call `simpleperf report` to
generate report file, and display it.
"""

import logging
import os
import os.path
import re
import subprocess
import sys

try:
    from tkinter import *
    from tkinter.font import Font
    from tkinter.ttk import *
except ImportError:
    from Tkinter import *
    from tkFont import Font
    from ttk import *

from simpleperf_utils import *

PAD_X = 3
PAD_Y = 3


class CallTreeNode(object):

    """Representing a node in call-graph."""

    def __init__(self, percentage, function_name):
        self.percentage = percentage
        self.call_stack = [function_name]
        self.children = []

    def add_call(self, function_name):
        self.call_stack.append(function_name)

    def add_child(self, node):
        self.children.append(node)

    def __str__(self):
        strs = self.dump()
        return '\n'.join(strs)

    def dump(self):
        strs = []
        strs.append('CallTreeNode percentage = %.2f' % self.percentage)
        for function_name in self.call_stack:
            strs.append(' %s' % function_name)
        for child in self.children:
            child_strs = child.dump()
            strs.extend(['  ' + x for x in child_strs])
        return strs


class ReportItem(object):

    """Representing one item in report, may contain a CallTree."""

    def __init__(self, raw_line):
        self.raw_line = raw_line
        self.call_tree = None

    def __str__(self):
        strs = []
        strs.append('ReportItem (raw_line %s)' % self.raw_line)
        if self.call_tree is not None:
            strs.append('%s' % self.call_tree)
        return '\n'.join(strs)


class EventReport(object):

    """Representing report for one event attr."""

    def __init__(self, common_report_context):
        self.context = common_report_context[:]
        self.title_line = None
        self.report_items = []


def parse_event_reports(lines):
    # Parse common report context
    common_report_context = []
    line_id = 0
    while line_id < len(lines):
        line = lines[line_id]
        if not line or line.find('Event:') == 0:
            break
        common_report_context.append(line)
        line_id += 1

    event_reports = []
    in_report_context = True
    cur_event_report = EventReport(common_report_context)
    cur_report_item = None
    call_tree_stack = {}
    vertical_columns = []
    last_node = None

    has_skipped_callgraph = False

    for line in lines[line_id:]:
        if not line:
            in_report_context = not in_report_context
            if in_report_context:
                cur_event_report = EventReport(common_report_context)
            continue

        if in_report_context:
            cur_event_report.context.append(line)
            if line.find('Event:') == 0:
                event_reports.append(cur_event_report)
            continue

        if cur_event_report.title_line is None:
            cur_event_report.title_line = line
        elif not line[0].isspace():
            cur_report_item = ReportItem(line)
            cur_event_report.report_items.append(cur_report_item)
            # Each report item can have different column depths.
            vertical_columns = []
        else:
            for i in range(len(line)):
                if line[i] == '|':
                    if not vertical_columns or vertical_columns[-1] < i:
                        vertical_columns.append(i)

            if not line.strip('| \t'):
                continue
            if 'skipped in brief callgraph mode' in line:
                has_skipped_callgraph = True
                continue

            if line.find('-') == -1:
                line = line.strip('| \t')
                function_name = line
                last_node.add_call(function_name)
            else:
                pos = line.find('-')
                depth = -1
                for i in range(len(vertical_columns)):
                    if pos >= vertical_columns[i]:
                        depth = i
                assert depth != -1

                line = line.strip('|- \t')
                m = re.search(r'^([\d\.]+)%[-\s]+(.+)$', line)
                if m:
                    percentage = float(m.group(1))
                    function_name = m.group(2)
                else:
                    percentage = 100.0
                    function_name = line

                node = CallTreeNode(percentage, function_name)
                if depth == 0:
                    cur_report_item.call_tree = node
                else:
                    call_tree_stack[depth - 1].add_child(node)
                call_tree_stack[depth] = node
                last_node = node

    if has_skipped_callgraph:
        logging.warning('some callgraphs are skipped in brief callgraph mode')

    return event_reports


class ReportWindow(object):

    """A window used to display report file."""

    def __init__(self, main, report_context, title_line, report_items):
        frame = Frame(main)
        frame.pack(fill=BOTH, expand=1)

        font = Font(family='courier', size=12)

        # Report Context
        for line in report_context:
            label = Label(frame, text=line, font=font)
            label.pack(anchor=W, padx=PAD_X, pady=PAD_Y)

        # Space
        label = Label(frame, text='', font=font)
        label.pack(anchor=W, padx=PAD_X, pady=PAD_Y)

        # Title
        label = Label(frame, text='  ' + title_line, font=font)
        label.pack(anchor=W, padx=PAD_X, pady=PAD_Y)

        # Report Items
        report_frame = Frame(frame)
        report_frame.pack(fill=BOTH, expand=1)

        yscrollbar = Scrollbar(report_frame)
        yscrollbar.pack(side=RIGHT, fill=Y)
        xscrollbar = Scrollbar(report_frame, orient=HORIZONTAL)
        xscrollbar.pack(side=BOTTOM, fill=X)

        tree = Treeview(report_frame, columns=[title_line], show='')
        tree.pack(side=LEFT, fill=BOTH, expand=1)
        tree.tag_configure('set_font', font=font)

        tree.config(yscrollcommand=yscrollbar.set)
        yscrollbar.config(command=tree.yview)
        tree.config(xscrollcommand=xscrollbar.set)
        xscrollbar.config(command=tree.xview)

        self.display_report_items(tree, report_items)

    def display_report_items(self, tree, report_items):
        for report_item in report_items:
            prefix_str = '+ ' if report_item.call_tree is not None else '  '
            id = tree.insert(
                '',
                'end',
                None,
                values=[
                    prefix_str +
                    report_item.raw_line],
                tag='set_font')
            if report_item.call_tree is not None:
                self.display_call_tree(tree, id, report_item.call_tree, 1)

    def display_call_tree(self, tree, parent_id, node, indent):
        id = parent_id
        indent_str = '    ' * indent

        if node.percentage != 100.0:
            percentage_str = '%.2f%% ' % node.percentage
        else:
            percentage_str = ''

        for i in range(len(node.call_stack)):
            s = indent_str
            s += '+ ' if node.children and i == len(node.call_stack) - 1 else '  '
            s += percentage_str if i == 0 else ' ' * len(percentage_str)
            s += node.call_stack[i]
            child_open = False if i == len(node.call_stack) - 1 and indent > 1 else True
            id = tree.insert(id, 'end', None, values=[s], open=child_open,
                             tag='set_font')

        for child in node.children:
            self.display_call_tree(tree, id, child, indent + 1)


def display_report_file(report_file, self_kill_after_sec):
    fh = open(report_file, 'r')
    lines = fh.readlines()
    fh.close()

    lines = [x.rstrip() for x in lines]
    event_reports = parse_event_reports(lines)

    if event_reports:
        root = Tk()
        for i in range(len(event_reports)):
            report = event_reports[i]
            parent = root if i == 0 else Toplevel(root)
            ReportWindow(parent, report.context, report.title_line, report.report_items)
        if self_kill_after_sec:
            root.after(self_kill_after_sec * 1000, lambda: root.destroy())
        root.mainloop()


def call_simpleperf_report(args, show_gui, self_kill_after_sec):
    simpleperf_path = get_host_binary_path('simpleperf')
    if not show_gui:
        subprocess.check_call([simpleperf_path, 'report'] + args)
    else:
        report_file = 'perf.report'
        subprocess.check_call([simpleperf_path, 'report', '--full-callgraph'] + args +
                              ['-o', report_file])
        display_report_file(report_file, self_kill_after_sec=self_kill_after_sec)


def get_simpleperf_report_help_msg():
    simpleperf_path = get_host_binary_path('simpleperf')
    args = [simpleperf_path, 'report', '-h']
    proc = subprocess.Popen(args, stdout=subprocess.PIPE)
    (stdoutdata, _) = proc.communicate()
    stdoutdata = bytes_to_str(stdoutdata)
    return stdoutdata[stdoutdata.find('\n') + 1:]


def main():
    self_kill_after_sec = 0
    args = sys.argv[1:]
    if args and args[0] == "--self-kill-for-testing":
        self_kill_after_sec = 1
        args = args[1:]
    if len(args) == 1 and os.path.isfile(args[0]):
        display_report_file(args[0], self_kill_after_sec=self_kill_after_sec)

    i = 0
    args_for_report_cmd = []
    show_gui = False
    while i < len(args):
        if args[i] == '-h' or args[i] == '--help':
            print('report.py   A python wrapper for simpleperf report command.')
            print('Options supported by simpleperf report command:')
            print(get_simpleperf_report_help_msg())
            print('\nOptions supported by report.py:')
            print('--gui   Show report result in a gui window.')
            print('\nIt also supports showing a report generated by simpleperf report cmd:')
            print('\n  python report.py report_file')
            sys.exit(0)
        elif args[i] == '--gui':
            show_gui = True
            i += 1
        else:
            args_for_report_cmd.append(args[i])
            i += 1

    call_simpleperf_report(args_for_report_cmd, show_gui, self_kill_after_sec)


if __name__ == '__main__':
    main()
