#!/usr/bin/env python
#
# 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 os.path
import re
import subprocess
import sys
from tkFont import *
from Tkinter import *
from ttk 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)


def parse_report_items(lines):
  report_items = []
  cur_report_item = None
  call_tree_stack = {}
  vertical_columns = []
  last_node = None

  for line in lines:
    if not line:
      continue
    if not line[0].isspace():
      cur_report_item = ReportItem(line)
      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 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

  return report_items


class ReportWindow(object):

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

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

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

    # 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 = ''
    first_open = True if node.percentage == 100.0 else False

    for i in range(len(node.call_stack)):
      s = indent_str
      s += '+ ' if node.children else '  '
      s += percentage_str if i == 0 else ' ' * len(percentage_str)
      s += node.call_stack[i]
      child_open = first_open if i == 0 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):
  fh = open(report_file, 'r')
  lines = fh.readlines()
  fh.close()

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

  blank_line_index = -1
  for i in range(len(lines)):
    if not lines[i]:
      blank_line_index = i
      break
  assert blank_line_index != -1
  assert blank_line_index + 1 < len(lines)

  report_context = lines[:blank_line_index]
  title_line = lines[blank_line_index + 1]
  report_items = parse_report_items(lines[blank_line_index + 2:])

  root = Tk()
  ReportWindow(root, report_context, title_line, report_items)
  root.mainloop()


def call_simpleperf_report(args, report_file):
  output_fh = open(report_file, 'w')
  args = ['simpleperf', 'report'] + args
  subprocess.check_call(args, stdout=output_fh)
  output_fh.close()


def main():
  if len(sys.argv) == 2 and os.path.isfile(sys.argv[1]):
    display_report_file(sys.argv[1])
  else:
    call_simpleperf_report(sys.argv[1:], 'perf.report')
    display_report_file('perf.report')


if __name__ == '__main__':
  main()
