#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2018 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.
#
# Interactive viewer for memd logs.  It displays the logged values and allows
# toggling individual graphs off and on.

"""Interactive visualizer of memd logs."""

from __future__ import print_function
from __future__ import division

import argparse
import glob
import math
import os
import sys
import warnings
import matplotlib.pyplot as plt

# Remove spurious warning from pyplot.
warnings.filterwarnings('ignore',
                        '.*Using default event loop until function ' +
                        'specific to this GUI is implemented.*')


def die(message):
  """Prints message and exits with error status."""
  print('memd_plot.py: fatal error:', message)
  sys.exit(1)

def warn(message):
  """Prints warning."""
  print('memd_plot.py: warning:', message)
  print(message)

def usage():
  """Prints usage message and exits"""
  die('usage: memd-plot.py <memd-log-directory>')


def eng_notation(x):
  """Converts number to string in engineering notation.

  Returns a formatted string for numeric value |x| rounded to an int in
  quasi-engineering notation, i.e:
    - if |x| is less than 1,000,000 use the standard integer format;
    - else use the <a>E<b> form where x = a * 10^b and b is a multiple of 3.
  """
  exponent = len(str(int(x))) - 1
  # Numbers up to 6 digits are easy to parse visually.
  if exponent < 6:
    return '%.7g' % x
  # Round exponent down to a multiple of 3.
  exponent = exponent - (exponent % 3)
  mantissa = x / (10 ** exponent)
  return '%.4gE^%s' % (mantissa, exponent)


def derivative(v1, v0, t1, t0):
  """Computes the difference quotient.

  Returns an approximation of the derivative dv/dt with special handling
  of delta(t) = 0.
  """
  if t1 > t0:
    return (v1 - v0) / (t1 - t0)
  else:
    return 0


# Dictionary keys that control pyplot keyboard bindings.
pyplot_keymap_entries = {}


def disable_pyplot_keymap():
  """Disables predefined pyplot keyboard bindings."""
  for name in pyplot_keymap_entries:
    plt.rcParams[name] = ''


def enable_pyplot_keymap():
  """Re-enables predefined pyplot keyboard bindings."""
  for name in pyplot_keymap_entries:
    plt.rcParams[name] = pyplot_keymap_entries[name]


def initialize_pyplot_keymap():
  """Saves the dictionary keys that control pyplot keyboard bindings."""
  for name in plt.rcParams:
    if name.startswith('keymap.'):
      pyplot_keymap_entries[name] = plt.rcParams[name]


color_table = [
    'black',
    'black',
    'black',
    'black',
    'black',
    'blue',
    'blue',
    'red',
    'red',
    '#ff0000',
    '#00ff00',
    '#0000ff',
    '#06cc16',
    '#c5960f',
    '#530072',
    '#b60ab4',
    '#0d757b',
    '#0ceb6c',
    '#4ba6ad',
    '#d00b03',
    '#e3240d',
    '#e60606',
    '#ffa19e',
    'olive',
    'orange',
    'salmon',
    'sienna',
    'tan',
    'plum',
    'maroon',
    'navy',
    'indigo',
    'darkgreen',
    'purple',
    'chocolate',
]


def color_for_name(name):
  """Computes a random but consistent RGB color for string |name|."""
  h = hash(name)
  # Generating good colors is difficult, so just use a table.
  return color_table[h % len(color_table)]


def linestyle_for_name(name):
  """Computes (and memorizes) a random line style for string |name|."""
  h = hash(name)
  styles = ['-', '-', '-', '--', '-.', ':']
  return styles[h % len(styles)]


next_label_key = 0
label_keys = {}
key_labels = {}


def add_grid(fig, max_x):
  """Adds a grid to the plot."""
  ax = fig.add_subplot(1, 1, 1)

  if max_x > 100:
    # The grid is too fine for plotting.  Ideally this should depend on the
    # current window on the plots, not the absolute maximum.
    return

  major_xticks = list(range(0, max_x, 5))
  minor_xticks = list(range(0, max_x, 1))
  major_yticks = list(range(0, 101, 10))
  minor_yticks = list(range(0, 101, 5))

  ax.set_xticks(major_xticks)
  ax.set_xticks(minor_xticks, minor=True)
  ax.set_yticks(major_yticks)
  ax.set_yticks(minor_yticks, minor=True)

  ax.grid(which='minor', alpha=0.5)
  ax.grid(which='major', alpha=1)


def round_up(x, digits):
  """Rounds up the |digits| most significant digits.

  For instance: round_up(12345, 2) returns 13000.
  """
  r = 10 ** (len(str(int(x))) - digits)
  return math.ceil(x / r) * r


def smooth_out(array, window_size):
  """Smooths out an array of values by averaging over a window."""
  for i in range(len(array) - 1, window_size - 2, -1):
    if array[i] is None:
      continue
    sample_count = 1
    for j in range(window_size - 1):
      v = array[i - (j + 1)]
      if v is not None:
        array[i] += v
        sample_count += 1
    array[i] /= float(sample_count)


def set_attribute(label, attribute_name, attribute_value):
  """Sets graph attribute |attribute_name| of |label| to |attribute_value|."""
  graph_attributes[label].update({attribute_name: attribute_value})


def clear_attribute(label, attribute_name):
  """Removes graph attribute |attribute_name| of |label|."""
  del graph_attributes[label][attribute_name]


def toggle_attribute(label, attribute_name):
  """Clears |attribute_name| of |label| if it is set, else sets it to True."""
  if attribute_name in graph_attributes[label]:
    clear_attribute(label, attribute_name)
  else:
    set_attribute(label, attribute_name, True)


# Tables that describe how various values/events are plotted.

# Graph_attributes is for time-varying values.
# Each graph is identified by its name (for instance, 'freeram'),
# also called 'label'.
#
# Graphs with 'ignore' == True are not plotted.
# Graphs with the same 'group' attribute are plotted with the same scale.
# 'off' == True: hides the graph at startup.
# 'differentiate' == True: plots the derivatives between samples.
# 'optional' == True: label is optional in samples.
graph_attributes = {
    # 'uptime' is treated specially since it is never plotted
    'uptime': {'ignore': True},
    # 'type' is also special because it is a string
    'type': {'ignore': True},

    'load': {
        'off': True,
        # Load averages returned by sysinfo need scaling.
        'scale': 1.0 / 65536,
    },
    'freeram': {
        'group': 'ram',
        'scale': 1e-3,
    },
    'freeswap': {
        'scale': 1e-3,
    },
    'procs': {
        'off': True,
    },
    'runnables': {
        'off': True,
        'smooth': 3
    },
    'available': {
        'group': 'ram',
        'scale': 1000,
    },
    'pswpin': {
        'differentiate': True,
        'group': 'pages',
        'off': True,
    },
    'pswpout': {
        'differentiate': True,
        'group': 'pages',
        'off': True,
    },
    'nr_pages_scanned': {
        'optional': True,
        'group': 'pages',
        'off': True,
    },
    'pgalloc': {
        'optional': True,
        'differentiate': True,
        'group': 'pages',
        'smooth': 3,
        'off': True,
    },
    'pgalloc_dma': {
        'optional': True,
        'differentiate': True,
        'group': 'pages',
        'smooth': 3,
        'off': True,
    },
    'pgalloc_dma32': {
        'optional': True,
        'differentiate': True,
        'group': 'pages',
        'smooth': 3,
        'off': True,
    },
    'pgalloc_normal': {
        'optional': True,
        'differentiate': True,
        'group': 'pages',
        'smooth': 3,
        'off': True,
    },
    'pgmajfault': {
        'differentiate': True,
        'group': 'pages',
        'off': True,
    },
    'pgmajfault_f': {
        'optional': True,
        'differentiate': True,
        'group': 'pages',
        'off': True,
    },
}


# Parameter_attributes describes fixed values, plotted as horizontal lines.
parameter_attributes = {
    'margin': {
        'group': 'ram',
        'scale': 1000,
    },
    'high_water_mark_kbytes': {
        'group': 'ram',
    },
    'min_water_mark_kbytes': {
        'group': 'ram',
    },
    'low_water_mark_kbytes': {
        'group': 'ram',
    },
}


# Event_attributes describes events, plotted as vertical lines.
event_attributes = {
    'lowmem': {
        'name': 'Enter Low Mem',
    },
    'lealow': {
        'name': 'Leave Low Mem',
    },
    'oomkll': {
        'name': 'OOM (from Chrome)',
    },
    'keroom': {
        'name': 'OOM (kernel time)',
    },
    'traoom': {
        'name': 'OOM (trace delivery)',
    },
    'discrd': {
        'name': 'Tab/App Discard',
    },
    'sleepr': {
        'name': 'Sleeper',
    },
}


max_values = {}
max_values_by_group = {}


class Plotter(object):
  """Methods to input, process and display memd samples."""

  def __init__(self, args):
    self._args = args
    self._samples = {}
    self._memd_parameters = {}
    self._label_key_index = 0
    self._needs_redisplay = True
    # Interactive input state
    self._ii_state = 'base'
    self._labels = {}
    self._plot_labels = {}

  def normalize_samples(self):
    """Normalizes the arrays of values in |samples|

    Values are modified according to the graph attributes.
    Additionally, expected and found label names are
    checked for consistency.
    """
    # Sanity check of sample labels against the name/labels in
    # graph_attributes.
    known_labels = set(graph_attributes.keys())
    required_labels = set([key for key in graph_attributes.keys()
                           if 'optional' not in graph_attributes[key]])
    found_labels = set(self._samples.keys())

    if not required_labels.issubset(found_labels):
      die('these required fields are missing:\n%s\n' %
          (sorted(required_labels.difference(found_labels))))

    if not found_labels.issubset(known_labels):
      warn('ignoring these unknown fields:\n%s\n' %
           (sorted(found_labels.difference(known_labels))))

    self._labels = found_labels & known_labels

    # Scale values by given scale factor (if any).
    # Also filter values (average over window, and compute derivative).
    # A bit hacky since there may be reboots.
    uptimes = self._samples['uptime']
    for label in self._labels:
      attr = graph_attributes[label]

      if 'ignore' in attr:
        continue

      scale = attr['scale'] if 'scale' in attr else 1
      self._samples[label] = [scale * x for x in self._samples[label]]

      if 'differentiate' in attr:
        s = self._samples[label]
        s = [derivative(s[i+1], s[i], uptimes[i+1], uptimes[i])
             for i in range(len(s) - 1)]
        s.append(0.0)
        self._samples[label] = s

      if 'smooth' in attr:
        window_size = attr['smooth']
        smooth_out(self._samples[label], window_size)

    # Shift uptimes to a zero base and adjust for gaps between clips, including
    # negative gaps due to reboots.
    offset = 0.0
    last_uptime = -1.0
    adjusted_uptimes = []
    for uptime in uptimes:
      # If the uptimes are not contiguous (i.e. at most about 0.1 seconds apart,
      # generously rounded up to 0.5) adjust offset so as to leave a 1-second
      # gap.
      if abs(uptime - last_uptime) > 0.5:
        offset += last_uptime - uptime + 1.0
      last_uptime = uptime
      adjusted_uptimes.append(uptime + offset)

    self._samples['uptime'] = adjusted_uptimes

    # Scale all values to between 0 and 100 so they can all be displayed in the
    # same graph.  This takes a few steps.

    # 1. Find groups of quantities that should be scaled equally.
    sample_groups = {}
    for label in self._labels:
      attr = graph_attributes[label]
      if 'group' in attr:
        group_name = attr['group']
        if group_name not in sample_groups:
          sample_groups[group_name] = set()
        sample_groups[group_name].add(label)

    # 2. Find max value for each group.
    for group_name in sample_groups:
      max_value = 0.0
      for label in sample_groups[group_name]:
        max_value = max(max_value, max(self._samples[label]))
      for label in sample_groups[group_name]:
        max_values[label] = max_value
      max_values_by_group[group_name] = max_value

    # Find max value for values that don't belong to any group.
    for label in self._labels:
      if label not in max_values and 'ignore' not in graph_attributes[label]:
        max_values[label] = max(self._samples[label])

    # Round up max values so that they aren't ugly.  This increases them a max
    # of 10%.
    for (label, value) in max_values.items():
      max_values[label] = round_up(value, 2)
    for (group_name, value) in max_values_by_group.items():
      max_values_by_group[group_name] = round_up(value, 2)

    # Scale so that max_value is mapped to 100.
    for label in max_values:
      m = max_values[label]
      self._samples[label] = [x / m * 100 for x in self._samples[label]]

  def add_gaps_to_samples(self):
    new_samples = {}
    for name in self._samples:
      new_samples[name] = []

    uptimes = self._samples['uptime']
    previous_uptime = -1.0
    for i, uptime in enumerate(uptimes):
      # Check for gap, but skip first (artificial) gap.  At each gap, insert a
      # None value in all value arrays, except uptime and type.
      if i > 0 and uptime > previous_uptime + 0.3:
        for name in self._samples:
          if name == 'uptime':
            new_samples[name].append(previous_uptime)
          elif name == 'type':
            new_samples[name].append('timer')
          else:
            new_samples[name].append(None)
      previous_uptime = uptime

      # Copy over old values.
      for name in self._samples:
        new_samples[name].append(self._samples[name][i])

    self._samples = new_samples

  def plot_values(self, label):
    """Plots the sampled values for label as a function of time."""

    on = 'off' not in graph_attributes[label]
    legend_entry = '%s) %s (100 = %s)' % (
        label_keys[label],
        label,
        eng_notation(max_values[label]))

    for v in self._samples[label]:
      if v and v < 0:
        die('negative value for %s: %s' % (label, v))

    plt.plot(self._samples['uptime'], self._samples[label],
             color=(color_for_name(label) if on else (1.0, 1.0, 1.0, 0)),
             linestyle=linestyle_for_name(label),
             label=legend_entry)

  def plot_redisplay(self, fig):
    """Redisplays the full graph."""

    plt.clf()
    add_grid(fig, int(self._samples['uptime'][-1]))

    # Graphs.
    for plot_label in sorted(self._plot_labels):
      self.plot_values(plot_label)

    # Events.
    uptimes = self._samples['uptime']
    event_types = self._samples['type']
    times = {name: [] for name in event_attributes}
    values = {name: [] for name in event_attributes}
    for i, uptime in enumerate(uptimes):
      event_type = event_types[i]
      if event_type == 'timer':
        continue

      # Create an isolated vertical line.
      times[event_type].append(uptime)
      values[event_type].append(105)
      times[event_type].append(uptime)
      values[event_type].append(-5)
      times[event_type].append(uptime)
      values[event_type].append(None)

    for event_type in event_attributes:
      if times[event_type]:
        plt.plot(times[event_type], values[event_type],
                 color=color_for_name(event_type),
                 linestyle=linestyle_for_name(event_type),
                 label=('| ' + event_attributes[event_type]['name']))

    times = self._samples['uptime']
    min_time = times[0]
    max_time = times[-1]
    for name in parameter_attributes:
      attr = parameter_attributes[name]
      parameter_value = self._memd_parameters[name]
      if 'scale' in attr:
        parameter_value *= attr['scale']
      if 'group' in attr:
        max_value = max_values_by_group[attr['group']]
        parameter_value /= max_value
        parameter_value *= 100
      legend_entry = '* %s (100 = %s)' % (name, eng_notation(max_value))
      plt.plot([min_time, max_time],
               [parameter_value, parameter_value],
               color=color_for_name(name),
               linestyle=linestyle_for_name(name),
               label=legend_entry)

    plt.legend(fontsize=12)

  def merge_pgalloc(self):
    """Combines the 'pgalloc_*' quantities into a single 'pgalloc'.

    Adds up all kinds of page allocation into a single one, for legacy logs.
    New logs are produced with a single 'pgalloc' quantity, old logs break it
    down by zone.
    """

    if 'pgalloc' in self._samples:
      return

    pgalloc_samples = None
    for (label, values) in self._samples.items():
      if label.startswith('pgalloc_'):
        if pgalloc_samples is None:
          pgalloc_samples = values[:]
        else:
          pgalloc_samples = [x + y for x, y in zip(pgalloc_samples, values)]
    self._samples['pgalloc'] = pgalloc_samples

  def run(self):
    """Reads the samples and plots them interactively."""
    field_names = None
    field_names_set = None
    lines = []

    print('available commands (in addition to pyplot standard commands):')
    print('t<key> - toggle graph <key> (see legend)')
    print('q      - quit')
    os.chdir(self._args['memd-log-directory'])
    filenames = glob.glob('memd.clip*.log') or die('there are no clip files')
    self.read_parameters()

    # Sort files by their time stamp (first line of each file)
    filenames = [x[0] for x in sorted([(name, next(open(name)))
                                       for name in filenames],
                                      key=lambda x: x[1])]

    # Read samples into |self._samples|.
    for filename in filenames:
      sample_file = open(filename)

      # Skip first line (time stamp).
      _ = next(sample_file)

      # Second line: field names.
      line = next(sample_file)
      if field_names:
        assert set(line.split()) == field_names_set
      else:
        field_names = line.split()
        field_names_set = set(field_names)
        self._samples = {field_name: [] for field_name in field_names}

      # Read the following lines, which contain samples.
      for line in sample_file:
        lines.append(line.split())

    # Build an array of values for each field.
    for line in lines:
      for name, value in zip(field_names, line):
        if name != 'type':
          value = float(value)
        self._samples[name].append(value)

    self.merge_pgalloc()
    self.normalize_samples()
    self.plot_samples()

  def read_parameters(self):
    """Reads the memd parameters file."""
    try:
      parameters_file = open('memd.parameters')
    except Exception:
      die('cannot open memd.parameters')

    for line in parameters_file.readlines()[1:]:
      name, value = line.split()
      self._memd_parameters[name] = int(value)

  def assign_keys_to_labels(self):
    self._plot_labels = [label for label in self._labels
                         if 'ignore' not in graph_attributes[label]]
    label_index = 0
    for label in sorted(self._plot_labels):
      key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[label_index]
      label_keys[label] = key
      key_labels[key] = label
      label_index += 1

  def plot_samples(self):
    """Does all the interactive plotting work."""
    # Add None values to create breaks in plotted lines.
    self.add_gaps_to_samples()
    self.assign_keys_to_labels()
    fig = plt.figure(figsize=(30, 10))
    fig.canvas.mpl_connect('key_press_event', self.keypress_callback)
    initialize_pyplot_keymap()
    self.plot_interactive(fig)

  def plot_interactive(self, fig):
    while self._ii_state != 'quit':
      if self._needs_redisplay:
        self.plot_redisplay(fig)
        self._needs_redisplay = False
      plt.waitforbuttonpress(0)

  def keypress_callback(self, event):
    """Callback for key press events."""
    key = event.key
    if self._ii_state == 'toggling':
      key = key.upper()
      if key in key_labels:
        label = key_labels[key.upper()]
        toggle_attribute(label, 'off')
        self._needs_redisplay = True
        enable_pyplot_keymap()
      else:
        print('no graph is associated with key "%s"' % key)
      self._ii_state = 'base'
    elif self._ii_state == 'base':
      if key == 'q':
        self._ii_state = 'quit'
      elif key == 't':
        self._ii_state = 'toggling'
        disable_pyplot_keymap()


def main():
  """Reads memd logs and interactively displays their content."""
  parser = argparse.ArgumentParser(
      description='Display memd logs interactively.')
  parser.add_argument('memd-log-directory')
  plotter = Plotter(vars(parser.parse_args()))
  plotter.run()


main()
