#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-only
#
# top-like utility for displaying kvm statistics
#
# Copyright 2006-2008 Qumranet Technologies
# Copyright 2008-2011 Red Hat, Inc.
#
# Authors:
#  Avi Kivity <avi@redhat.com>
#
"""The kvm_stat module outputs statistics about running KVM VMs

Three different ways of output formatting are available:
- as a top-like text ui
- in a key -> value format
- in an all keys, all values format

The data is sampled from the KVM's debugfs entries and its perf events.
"""
from __future__ import print_function

import curses
import sys
import locale
import os
import time
import optparse
import ctypes
import fcntl
import resource
import struct
import re
import subprocess
from collections import defaultdict, namedtuple

VMX_EXIT_REASONS = {
    'EXCEPTION_NMI':        0,
    'EXTERNAL_INTERRUPT':   1,
    'TRIPLE_FAULT':         2,
    'PENDING_INTERRUPT':    7,
    'NMI_WINDOW':           8,
    'TASK_SWITCH':          9,
    'CPUID':                10,
    'HLT':                  12,
    'INVLPG':               14,
    'RDPMC':                15,
    'RDTSC':                16,
    'VMCALL':               18,
    'VMCLEAR':              19,
    'VMLAUNCH':             20,
    'VMPTRLD':              21,
    'VMPTRST':              22,
    'VMREAD':               23,
    'VMRESUME':             24,
    'VMWRITE':              25,
    'VMOFF':                26,
    'VMON':                 27,
    'CR_ACCESS':            28,
    'DR_ACCESS':            29,
    'IO_INSTRUCTION':       30,
    'MSR_READ':             31,
    'MSR_WRITE':            32,
    'INVALID_STATE':        33,
    'MWAIT_INSTRUCTION':    36,
    'MONITOR_INSTRUCTION':  39,
    'PAUSE_INSTRUCTION':    40,
    'MCE_DURING_VMENTRY':   41,
    'TPR_BELOW_THRESHOLD':  43,
    'APIC_ACCESS':          44,
    'EPT_VIOLATION':        48,
    'EPT_MISCONFIG':        49,
    'WBINVD':               54,
    'XSETBV':               55,
    'APIC_WRITE':           56,
    'INVPCID':              58,
}

SVM_EXIT_REASONS = {
    'READ_CR0':       0x000,
    'READ_CR3':       0x003,
    'READ_CR4':       0x004,
    'READ_CR8':       0x008,
    'WRITE_CR0':      0x010,
    'WRITE_CR3':      0x013,
    'WRITE_CR4':      0x014,
    'WRITE_CR8':      0x018,
    'READ_DR0':       0x020,
    'READ_DR1':       0x021,
    'READ_DR2':       0x022,
    'READ_DR3':       0x023,
    'READ_DR4':       0x024,
    'READ_DR5':       0x025,
    'READ_DR6':       0x026,
    'READ_DR7':       0x027,
    'WRITE_DR0':      0x030,
    'WRITE_DR1':      0x031,
    'WRITE_DR2':      0x032,
    'WRITE_DR3':      0x033,
    'WRITE_DR4':      0x034,
    'WRITE_DR5':      0x035,
    'WRITE_DR6':      0x036,
    'WRITE_DR7':      0x037,
    'EXCP_BASE':      0x040,
    'INTR':           0x060,
    'NMI':            0x061,
    'SMI':            0x062,
    'INIT':           0x063,
    'VINTR':          0x064,
    'CR0_SEL_WRITE':  0x065,
    'IDTR_READ':      0x066,
    'GDTR_READ':      0x067,
    'LDTR_READ':      0x068,
    'TR_READ':        0x069,
    'IDTR_WRITE':     0x06a,
    'GDTR_WRITE':     0x06b,
    'LDTR_WRITE':     0x06c,
    'TR_WRITE':       0x06d,
    'RDTSC':          0x06e,
    'RDPMC':          0x06f,
    'PUSHF':          0x070,
    'POPF':           0x071,
    'CPUID':          0x072,
    'RSM':            0x073,
    'IRET':           0x074,
    'SWINT':          0x075,
    'INVD':           0x076,
    'PAUSE':          0x077,
    'HLT':            0x078,
    'INVLPG':         0x079,
    'INVLPGA':        0x07a,
    'IOIO':           0x07b,
    'MSR':            0x07c,
    'TASK_SWITCH':    0x07d,
    'FERR_FREEZE':    0x07e,
    'SHUTDOWN':       0x07f,
    'VMRUN':          0x080,
    'VMMCALL':        0x081,
    'VMLOAD':         0x082,
    'VMSAVE':         0x083,
    'STGI':           0x084,
    'CLGI':           0x085,
    'SKINIT':         0x086,
    'RDTSCP':         0x087,
    'ICEBP':          0x088,
    'WBINVD':         0x089,
    'MONITOR':        0x08a,
    'MWAIT':          0x08b,
    'MWAIT_COND':     0x08c,
    'XSETBV':         0x08d,
    'NPF':            0x400,
}

# EC definition of HSR (from arch/arm64/include/asm/kvm_arm.h)
AARCH64_EXIT_REASONS = {
    'UNKNOWN':      0x00,
    'WFI':          0x01,
    'CP15_32':      0x03,
    'CP15_64':      0x04,
    'CP14_MR':      0x05,
    'CP14_LS':      0x06,
    'FP_ASIMD':     0x07,
    'CP10_ID':      0x08,
    'CP14_64':      0x0C,
    'ILL_ISS':      0x0E,
    'SVC32':        0x11,
    'HVC32':        0x12,
    'SMC32':        0x13,
    'SVC64':        0x15,
    'HVC64':        0x16,
    'SMC64':        0x17,
    'SYS64':        0x18,
    'IABT':         0x20,
    'IABT_HYP':     0x21,
    'PC_ALIGN':     0x22,
    'DABT':         0x24,
    'DABT_HYP':     0x25,
    'SP_ALIGN':     0x26,
    'FP_EXC32':     0x28,
    'FP_EXC64':     0x2C,
    'SERROR':       0x2F,
    'BREAKPT':      0x30,
    'BREAKPT_HYP':  0x31,
    'SOFTSTP':      0x32,
    'SOFTSTP_HYP':  0x33,
    'WATCHPT':      0x34,
    'WATCHPT_HYP':  0x35,
    'BKPT32':       0x38,
    'VECTOR32':     0x3A,
    'BRK64':        0x3C,
}

# From include/uapi/linux/kvm.h, KVM_EXIT_xxx
USERSPACE_EXIT_REASONS = {
    'UNKNOWN':          0,
    'EXCEPTION':        1,
    'IO':               2,
    'HYPERCALL':        3,
    'DEBUG':            4,
    'HLT':              5,
    'MMIO':             6,
    'IRQ_WINDOW_OPEN':  7,
    'SHUTDOWN':         8,
    'FAIL_ENTRY':       9,
    'INTR':             10,
    'SET_TPR':          11,
    'TPR_ACCESS':       12,
    'S390_SIEIC':       13,
    'S390_RESET':       14,
    'DCR':              15,
    'NMI':              16,
    'INTERNAL_ERROR':   17,
    'OSI':              18,
    'PAPR_HCALL':       19,
    'S390_UCONTROL':    20,
    'WATCHDOG':         21,
    'S390_TSCH':        22,
    'EPR':              23,
    'SYSTEM_EVENT':     24,
}

IOCTL_NUMBERS = {
    'SET_FILTER':  0x40082406,
    'ENABLE':      0x00002400,
    'DISABLE':     0x00002401,
    'RESET':       0x00002403,
}

ENCODING = locale.getpreferredencoding(False)
TRACE_FILTER = re.compile(r'^[^\(]*$')


class Arch(object):
    """Encapsulates global architecture specific data.

    Contains the performance event open syscall and ioctl numbers, as
    well as the VM exit reasons for the architecture it runs on.

    """
    @staticmethod
    def get_arch():
        machine = os.uname()[4]

        if machine.startswith('ppc'):
            return ArchPPC()
        elif machine.startswith('aarch64'):
            return ArchA64()
        elif machine.startswith('s390'):
            return ArchS390()
        else:
            # X86_64
            for line in open('/proc/cpuinfo'):
                if not line.startswith('flags'):
                    continue

                flags = line.split()
                if 'vmx' in flags:
                    return ArchX86(VMX_EXIT_REASONS)
                if 'svm' in flags:
                    return ArchX86(SVM_EXIT_REASONS)
                return

    def tracepoint_is_child(self, field):
        if (TRACE_FILTER.match(field)):
            return None
        return field.split('(', 1)[0]


class ArchX86(Arch):
    def __init__(self, exit_reasons):
        self.sc_perf_evt_open = 298
        self.ioctl_numbers = IOCTL_NUMBERS
        self.exit_reasons = exit_reasons

    def debugfs_is_child(self, field):
        """ Returns name of parent if 'field' is a child, None otherwise """
        return None


class ArchPPC(Arch):
    def __init__(self):
        self.sc_perf_evt_open = 319
        self.ioctl_numbers = IOCTL_NUMBERS
        self.ioctl_numbers['ENABLE'] = 0x20002400
        self.ioctl_numbers['DISABLE'] = 0x20002401
        self.ioctl_numbers['RESET'] = 0x20002403

        # PPC comes in 32 and 64 bit and some generated ioctl
        # numbers depend on the wordsize.
        char_ptr_size = ctypes.sizeof(ctypes.c_char_p)
        self.ioctl_numbers['SET_FILTER'] = 0x80002406 | char_ptr_size << 16
        self.exit_reasons = {}

    def debugfs_is_child(self, field):
        """ Returns name of parent if 'field' is a child, None otherwise """
        return None


class ArchA64(Arch):
    def __init__(self):
        self.sc_perf_evt_open = 241
        self.ioctl_numbers = IOCTL_NUMBERS
        self.exit_reasons = AARCH64_EXIT_REASONS

    def debugfs_is_child(self, field):
        """ Returns name of parent if 'field' is a child, None otherwise """
        return None


class ArchS390(Arch):
    def __init__(self):
        self.sc_perf_evt_open = 331
        self.ioctl_numbers = IOCTL_NUMBERS
        self.exit_reasons = None

    def debugfs_is_child(self, field):
        """ Returns name of parent if 'field' is a child, None otherwise """
        if field.startswith('instruction_'):
            return 'exit_instruction'


ARCH = Arch.get_arch()


class perf_event_attr(ctypes.Structure):
    """Struct that holds the necessary data to set up a trace event.

    For an extensive explanation see perf_event_open(2) and
    include/uapi/linux/perf_event.h, struct perf_event_attr

    All fields that are not initialized in the constructor are 0.

    """
    _fields_ = [('type', ctypes.c_uint32),
                ('size', ctypes.c_uint32),
                ('config', ctypes.c_uint64),
                ('sample_freq', ctypes.c_uint64),
                ('sample_type', ctypes.c_uint64),
                ('read_format', ctypes.c_uint64),
                ('flags', ctypes.c_uint64),
                ('wakeup_events', ctypes.c_uint32),
                ('bp_type', ctypes.c_uint32),
                ('bp_addr', ctypes.c_uint64),
                ('bp_len', ctypes.c_uint64),
                ]

    def __init__(self):
        super(self.__class__, self).__init__()
        self.type = PERF_TYPE_TRACEPOINT
        self.size = ctypes.sizeof(self)
        self.read_format = PERF_FORMAT_GROUP


PERF_TYPE_TRACEPOINT = 2
PERF_FORMAT_GROUP = 1 << 3


class Group(object):
    """Represents a perf event group."""

    def __init__(self):
        self.events = []

    def add_event(self, event):
        self.events.append(event)

    def read(self):
        """Returns a dict with 'event name: value' for all events in the
        group.

        Values are read by reading from the file descriptor of the
        event that is the group leader. See perf_event_open(2) for
        details.

        Read format for the used event configuration is:
        struct read_format {
            u64 nr; /* The number of events */
            struct {
                u64 value; /* The value of the event */
            } values[nr];
        };

        """
        length = 8 * (1 + len(self.events))
        read_format = 'xxxxxxxx' + 'Q' * len(self.events)
        return dict(zip([event.name for event in self.events],
                        struct.unpack(read_format,
                                      os.read(self.events[0].fd, length))))


class Event(object):
    """Represents a performance event and manages its life cycle."""
    def __init__(self, name, group, trace_cpu, trace_pid, trace_point,
                 trace_filter, trace_set='kvm'):
        self.libc = ctypes.CDLL('libc.so.6', use_errno=True)
        self.syscall = self.libc.syscall
        self.name = name
        self.fd = None
        self._setup_event(group, trace_cpu, trace_pid, trace_point,
                          trace_filter, trace_set)

    def __del__(self):
        """Closes the event's file descriptor.

        As no python file object was created for the file descriptor,
        python will not reference count the descriptor and will not
        close it itself automatically, so we do it.

        """
        if self.fd:
            os.close(self.fd)

    def _perf_event_open(self, attr, pid, cpu, group_fd, flags):
        """Wrapper for the sys_perf_evt_open() syscall.

        Used to set up performance events, returns a file descriptor or -1
        on error.

        Attributes are:
        - syscall number
        - struct perf_event_attr *
        - pid or -1 to monitor all pids
        - cpu number or -1 to monitor all cpus
        - The file descriptor of the group leader or -1 to create a group.
        - flags

        """
        return self.syscall(ARCH.sc_perf_evt_open, ctypes.pointer(attr),
                            ctypes.c_int(pid), ctypes.c_int(cpu),
                            ctypes.c_int(group_fd), ctypes.c_long(flags))

    def _setup_event_attribute(self, trace_set, trace_point):
        """Returns an initialized ctype perf_event_attr struct."""

        id_path = os.path.join(PATH_DEBUGFS_TRACING, 'events', trace_set,
                               trace_point, 'id')

        event_attr = perf_event_attr()
        event_attr.config = int(open(id_path).read())
        return event_attr

    def _setup_event(self, group, trace_cpu, trace_pid, trace_point,
                     trace_filter, trace_set):
        """Sets up the perf event in Linux.

        Issues the syscall to register the event in the kernel and
        then sets the optional filter.

        """

        event_attr = self._setup_event_attribute(trace_set, trace_point)

        # First event will be group leader.
        group_leader = -1

        # All others have to pass the leader's descriptor instead.
        if group.events:
            group_leader = group.events[0].fd

        fd = self._perf_event_open(event_attr, trace_pid,
                                   trace_cpu, group_leader, 0)
        if fd == -1:
            err = ctypes.get_errno()
            raise OSError(err, os.strerror(err),
                          'while calling sys_perf_event_open().')

        if trace_filter:
            fcntl.ioctl(fd, ARCH.ioctl_numbers['SET_FILTER'],
                        trace_filter)

        self.fd = fd

    def enable(self):
        """Enables the trace event in the kernel.

        Enabling the group leader makes reading counters from it and the
        events under it possible.

        """
        fcntl.ioctl(self.fd, ARCH.ioctl_numbers['ENABLE'], 0)

    def disable(self):
        """Disables the trace event in the kernel.

        Disabling the group leader makes reading all counters under it
        impossible.

        """
        fcntl.ioctl(self.fd, ARCH.ioctl_numbers['DISABLE'], 0)

    def reset(self):
        """Resets the count of the trace event in the kernel."""
        fcntl.ioctl(self.fd, ARCH.ioctl_numbers['RESET'], 0)


class Provider(object):
    """Encapsulates functionalities used by all providers."""
    def __init__(self, pid):
        self.child_events = False
        self.pid = pid

    @staticmethod
    def is_field_wanted(fields_filter, field):
        """Indicate whether field is valid according to fields_filter."""
        if not fields_filter:
            return True
        return re.match(fields_filter, field) is not None

    @staticmethod
    def walkdir(path):
        """Returns os.walk() data for specified directory.

        As it is only a wrapper it returns the same 3-tuple of (dirpath,
        dirnames, filenames).
        """
        return next(os.walk(path))


class TracepointProvider(Provider):
    """Data provider for the stats class.

    Manages the events/groups from which it acquires its data.

    """
    def __init__(self, pid, fields_filter):
        self.group_leaders = []
        self.filters = self._get_filters()
        self.update_fields(fields_filter)
        super(TracepointProvider, self).__init__(pid)

    @staticmethod
    def _get_filters():
        """Returns a dict of trace events, their filter ids and
        the values that can be filtered.

        Trace events can be filtered for special values by setting a
        filter string via an ioctl. The string normally has the format
        identifier==value. For each filter a new event will be created, to
        be able to distinguish the events.

        """
        filters = {}
        filters['kvm_userspace_exit'] = ('reason', USERSPACE_EXIT_REASONS)
        if ARCH.exit_reasons:
            filters['kvm_exit'] = ('exit_reason', ARCH.exit_reasons)
        return filters

    def _get_available_fields(self):
        """Returns a list of available events of format 'event name(filter
        name)'.

        All available events have directories under
        /sys/kernel/debug/tracing/events/ which export information
        about the specific event. Therefore, listing the dirs gives us
        a list of all available events.

        Some events like the vm exit reasons can be filtered for
        specific values. To take account for that, the routine below
        creates special fields with the following format:
        event name(filter name)

        """
        path = os.path.join(PATH_DEBUGFS_TRACING, 'events', 'kvm')
        fields = self.walkdir(path)[1]
        extra = []
        for field in fields:
            if field in self.filters:
                filter_name_, filter_dicts = self.filters[field]
                for name in filter_dicts:
                    extra.append(field + '(' + name + ')')
        fields += extra
        return fields

    def update_fields(self, fields_filter):
        """Refresh fields, applying fields_filter"""
        self.fields = [field for field in self._get_available_fields()
                       if self.is_field_wanted(fields_filter, field)]
        # add parents for child fields - otherwise we won't see any output!
        for field in self._fields:
            parent = ARCH.tracepoint_is_child(field)
            if (parent and parent not in self._fields):
                self.fields.append(parent)

    @staticmethod
    def _get_online_cpus():
        """Returns a list of cpu id integers."""
        def parse_int_list(list_string):
            """Returns an int list from a string of comma separated integers and
            integer ranges."""
            integers = []
            members = list_string.split(',')

            for member in members:
                if '-' not in member:
                    integers.append(int(member))
                else:
                    int_range = member.split('-')
                    integers.extend(range(int(int_range[0]),
                                          int(int_range[1]) + 1))

            return integers

        with open('/sys/devices/system/cpu/online') as cpu_list:
            cpu_string = cpu_list.readline()
            return parse_int_list(cpu_string)

    def _setup_traces(self):
        """Creates all event and group objects needed to be able to retrieve
        data."""
        fields = self._get_available_fields()
        if self._pid > 0:
            # Fetch list of all threads of the monitored pid, as qemu
            # starts a thread for each vcpu.
            path = os.path.join('/proc', str(self._pid), 'task')
            groupids = self.walkdir(path)[1]
        else:
            groupids = self._get_online_cpus()

        # The constant is needed as a buffer for python libs, std
        # streams and other files that the script opens.
        newlim = len(groupids) * len(fields) + 50
        try:
            softlim_, hardlim = resource.getrlimit(resource.RLIMIT_NOFILE)

            if hardlim < newlim:
                # Now we need CAP_SYS_RESOURCE, to increase the hard limit.
                resource.setrlimit(resource.RLIMIT_NOFILE, (newlim, newlim))
            else:
                # Raising the soft limit is sufficient.
                resource.setrlimit(resource.RLIMIT_NOFILE, (newlim, hardlim))

        except ValueError:
            sys.exit("NOFILE rlimit could not be raised to {0}".format(newlim))

        for groupid in groupids:
            group = Group()
            for name in fields:
                tracepoint = name
                tracefilter = None
                match = re.match(r'(.*)\((.*)\)', name)
                if match:
                    tracepoint, sub = match.groups()
                    tracefilter = ('%s==%d\0' %
                                   (self.filters[tracepoint][0],
                                    self.filters[tracepoint][1][sub]))

                # From perf_event_open(2):
                # pid > 0 and cpu == -1
                # This measures the specified process/thread on any CPU.
                #
                # pid == -1 and cpu >= 0
                # This measures all processes/threads on the specified CPU.
                trace_cpu = groupid if self._pid == 0 else -1
                trace_pid = int(groupid) if self._pid != 0 else -1

                group.add_event(Event(name=name,
                                      group=group,
                                      trace_cpu=trace_cpu,
                                      trace_pid=trace_pid,
                                      trace_point=tracepoint,
                                      trace_filter=tracefilter))

            self.group_leaders.append(group)

    @property
    def fields(self):
        return self._fields

    @fields.setter
    def fields(self, fields):
        """Enables/disables the (un)wanted events"""
        self._fields = fields
        for group in self.group_leaders:
            for index, event in enumerate(group.events):
                if event.name in fields:
                    event.reset()
                    event.enable()
                else:
                    # Do not disable the group leader.
                    # It would disable all of its events.
                    if index != 0:
                        event.disable()

    @property
    def pid(self):
        return self._pid

    @pid.setter
    def pid(self, pid):
        """Changes the monitored pid by setting new traces."""
        self._pid = pid
        # The garbage collector will get rid of all Event/Group
        # objects and open files after removing the references.
        self.group_leaders = []
        self._setup_traces()
        self.fields = self._fields

    def read(self, by_guest=0):
        """Returns 'event name: current value' for all enabled events."""
        ret = defaultdict(int)
        for group in self.group_leaders:
            for name, val in group.read().items():
                if name not in self._fields:
                    continue
                parent = ARCH.tracepoint_is_child(name)
                if parent:
                    name += ' ' + parent
                ret[name] += val
        return ret

    def reset(self):
        """Reset all field counters"""
        for group in self.group_leaders:
            for event in group.events:
                event.reset()


class DebugfsProvider(Provider):
    """Provides data from the files that KVM creates in the kvm debugfs
    folder."""
    def __init__(self, pid, fields_filter, include_past):
        self.update_fields(fields_filter)
        self._baseline = {}
        self.do_read = True
        self.paths = []
        super(DebugfsProvider, self).__init__(pid)
        if include_past:
            self._restore()

    def _get_available_fields(self):
        """"Returns a list of available fields.

        The fields are all available KVM debugfs files

        """
        return self.walkdir(PATH_DEBUGFS_KVM)[2]

    def update_fields(self, fields_filter):
        """Refresh fields, applying fields_filter"""
        self._fields = [field for field in self._get_available_fields()
                        if self.is_field_wanted(fields_filter, field)]
        # add parents for child fields - otherwise we won't see any output!
        for field in self._fields:
            parent = ARCH.debugfs_is_child(field)
            if (parent and parent not in self._fields):
                self.fields.append(parent)

    @property
    def fields(self):
        return self._fields

    @fields.setter
    def fields(self, fields):
        self._fields = fields
        self.reset()

    @property
    def pid(self):
        return self._pid

    @pid.setter
    def pid(self, pid):
        self._pid = pid
        if pid != 0:
            vms = self.walkdir(PATH_DEBUGFS_KVM)[1]
            if len(vms) == 0:
                self.do_read = False

            self.paths = list(filter(lambda x: "{}-".format(pid) in x, vms))

        else:
            self.paths = []
            self.do_read = True

    def _verify_paths(self):
        """Remove invalid paths"""
        for path in self.paths:
            if not os.path.exists(os.path.join(PATH_DEBUGFS_KVM, path)):
                self.paths.remove(path)
                continue

    def read(self, reset=0, by_guest=0):
        """Returns a dict with format:'file name / field -> current value'.

        Parameter 'reset':
          0   plain read
          1   reset field counts to 0
          2   restore the original field counts

        """
        results = {}

        # If no debugfs filtering support is available, then don't read.
        if not self.do_read:
            return results
        self._verify_paths()

        paths = self.paths
        if self._pid == 0:
            paths = []
            for entry in os.walk(PATH_DEBUGFS_KVM):
                for dir in entry[1]:
                    paths.append(dir)
        for path in paths:
            for field in self._fields:
                value = self._read_field(field, path)
                key = path + field
                if reset == 1:
                    self._baseline[key] = value
                if reset == 2:
                    self._baseline[key] = 0
                if self._baseline.get(key, -1) == -1:
                    self._baseline[key] = value
                parent = ARCH.debugfs_is_child(field)
                if parent:
                    field = field + ' ' + parent
                else:
                    if by_guest:
                        field = key.split('-')[0]    # set 'field' to 'pid'
                increment = value - self._baseline.get(key, 0)
                if field in results:
                    results[field] += increment
                else:
                    results[field] = increment

        return results

    def _read_field(self, field, path):
        """Returns the value of a single field from a specific VM."""
        try:
            return int(open(os.path.join(PATH_DEBUGFS_KVM,
                                         path,
                                         field))
                       .read())
        except IOError:
            return 0

    def reset(self):
        """Reset field counters"""
        self._baseline = {}
        self.read(1)

    def _restore(self):
        """Reset field counters"""
        self._baseline = {}
        self.read(2)


EventStat = namedtuple('EventStat', ['value', 'delta'])


class Stats(object):
    """Manages the data providers and the data they provide.

    It is used to set filters on the provider's data and collect all
    provider data.

    """
    def __init__(self, options):
        self.providers = self._get_providers(options)
        self._pid_filter = options.pid
        self._fields_filter = options.fields
        self.values = {}
        self._child_events = False

    def _get_providers(self, options):
        """Returns a list of data providers depending on the passed options."""
        providers = []

        if options.debugfs:
            providers.append(DebugfsProvider(options.pid, options.fields,
                                             options.dbgfs_include_past))
        if options.tracepoints or not providers:
            providers.append(TracepointProvider(options.pid, options.fields))

        return providers

    def _update_provider_filters(self):
        """Propagates fields filters to providers."""
        # As we reset the counters when updating the fields we can
        # also clear the cache of old values.
        self.values = {}
        for provider in self.providers:
            provider.update_fields(self._fields_filter)

    def reset(self):
        self.values = {}
        for provider in self.providers:
            provider.reset()

    @property
    def fields_filter(self):
        return self._fields_filter

    @fields_filter.setter
    def fields_filter(self, fields_filter):
        if fields_filter != self._fields_filter:
            self._fields_filter = fields_filter
            self._update_provider_filters()

    @property
    def pid_filter(self):
        return self._pid_filter

    @pid_filter.setter
    def pid_filter(self, pid):
        if pid != self._pid_filter:
            self._pid_filter = pid
            self.values = {}
            for provider in self.providers:
                provider.pid = self._pid_filter

    @property
    def child_events(self):
        return self._child_events

    @child_events.setter
    def child_events(self, val):
        self._child_events = val
        for provider in self.providers:
            provider.child_events = val

    def get(self, by_guest=0):
        """Returns a dict with field -> (value, delta to last value) of all
        provider data.
        Key formats:
          * plain: 'key' is event name
          * child-parent: 'key' is in format '<child> <parent>'
          * pid: 'key' is the pid of the guest, and the record contains the
               aggregated event data
        These formats are generated by the providers, and handled in class TUI.
        """
        for provider in self.providers:
            new = provider.read(by_guest=by_guest)
            for key in new:
                oldval = self.values.get(key, EventStat(0, 0)).value
                newval = new.get(key, 0)
                newdelta = newval - oldval
                self.values[key] = EventStat(newval, newdelta)
        return self.values

    def toggle_display_guests(self, to_pid):
        """Toggle between collection of stats by individual event and by
        guest pid

        Events reported by DebugfsProvider change when switching to/from
        reading by guest values. Hence we have to remove the excess event
        names from self.values.

        """
        if any(isinstance(ins, TracepointProvider) for ins in self.providers):
            return 1
        if to_pid:
            for provider in self.providers:
                if isinstance(provider, DebugfsProvider):
                    for key in provider.fields:
                        if key in self.values.keys():
                            del self.values[key]
        else:
            oldvals = self.values.copy()
            for key in oldvals:
                if key.isdigit():
                    del self.values[key]
        # Update oldval (see get())
        self.get(to_pid)
        return 0


DELAY_DEFAULT = 3.0
MAX_GUEST_NAME_LEN = 48
MAX_REGEX_LEN = 44
SORT_DEFAULT = 0


class Tui(object):
    """Instruments curses to draw a nice text ui."""
    def __init__(self, stats):
        self.stats = stats
        self.screen = None
        self._delay_initial = 0.25
        self._delay_regular = DELAY_DEFAULT
        self._sorting = SORT_DEFAULT
        self._display_guests = 0

    def __enter__(self):
        """Initialises curses for later use.  Based on curses.wrapper
           implementation from the Python standard library."""
        self.screen = curses.initscr()
        curses.noecho()
        curses.cbreak()

        # The try/catch works around a minor bit of
        # over-conscientiousness in the curses module, the error
        # return from C start_color() is ignorable.
        try:
            curses.start_color()
        except curses.error:
            pass

        # Hide cursor in extra statement as some monochrome terminals
        # might support hiding but not colors.
        try:
            curses.curs_set(0)
        except curses.error:
            pass

        curses.use_default_colors()
        return self

    def __exit__(self, *exception):
        """Resets the terminal to its normal state.  Based on curses.wrapper
           implementation from the Python standard library."""
        if self.screen:
            self.screen.keypad(0)
            curses.echo()
            curses.nocbreak()
            curses.endwin()

    @staticmethod
    def get_all_gnames():
        """Returns a list of (pid, gname) tuples of all running guests"""
        res = []
        try:
            child = subprocess.Popen(['ps', '-A', '--format', 'pid,args'],
                                     stdout=subprocess.PIPE)
        except:
            raise Exception
        for line in child.stdout:
            line = line.decode(ENCODING).lstrip().split(' ', 1)
            # perform a sanity check before calling the more expensive
            # function to possibly extract the guest name
            if ' -name ' in line[1]:
                res.append((line[0], Tui.get_gname_from_pid(line[0])))
        child.stdout.close()

        return res

    def _print_all_gnames(self, row):
        """Print a list of all running guests along with their pids."""
        self.screen.addstr(row, 2, '%8s  %-60s' %
                           ('Pid', 'Guest Name (fuzzy list, might be '
                            'inaccurate!)'),
                           curses.A_UNDERLINE)
        row += 1
        try:
            for line in self.get_all_gnames():
                self.screen.addstr(row, 2, '%8s  %-60s' % (line[0], line[1]))
                row += 1
                if row >= self.screen.getmaxyx()[0]:
                    break
        except Exception:
            self.screen.addstr(row + 1, 2, 'Not available')

    @staticmethod
    def get_pid_from_gname(gname):
        """Fuzzy function to convert guest name to QEMU process pid.

        Returns a list of potential pids, can be empty if no match found.
        Throws an exception on processing errors.

        """
        pids = []
        for line in Tui.get_all_gnames():
            if gname == line[1]:
                pids.append(int(line[0]))

        return pids

    @staticmethod
    def get_gname_from_pid(pid):
        """Returns the guest name for a QEMU process pid.

        Extracts the guest name from the QEMU comma line by processing the
        '-name' option. Will also handle names specified out of sequence.

        """
        name = ''
        try:
            line = open('/proc/{}/cmdline'
                        .format(pid), 'r').read().split('\0')
            parms = line[line.index('-name') + 1].split(',')
            while '' in parms:
                # commas are escaped (i.e. ',,'), hence e.g. 'foo,bar' results
                # in # ['foo', '', 'bar'], which we revert here
                idx = parms.index('')
                parms[idx - 1] += ',' + parms[idx + 1]
                del parms[idx:idx+2]
            # the '-name' switch allows for two ways to specify the guest name,
            # where the plain name overrides the name specified via 'guest='
            for arg in parms:
                if '=' not in arg:
                    name = arg
                    break
                if arg[:6] == 'guest=':
                    name = arg[6:]
        except (ValueError, IOError, IndexError):
            pass

        return name

    def _update_pid(self, pid):
        """Propagates pid selection to stats object."""
        self.screen.addstr(4, 1, 'Updating pid filter...')
        self.screen.refresh()
        self.stats.pid_filter = pid

    def _refresh_header(self, pid=None):
        """Refreshes the header."""
        if pid is None:
            pid = self.stats.pid_filter
        self.screen.erase()
        gname = self.get_gname_from_pid(pid)
        self._gname = gname
        if gname:
            gname = ('({})'.format(gname[:MAX_GUEST_NAME_LEN] + '...'
                                   if len(gname) > MAX_GUEST_NAME_LEN
                                   else gname))
        if pid > 0:
            self._headline = 'kvm statistics - pid {0} {1}'.format(pid, gname)
        else:
            self._headline = 'kvm statistics - summary'
        self.screen.addstr(0, 0, self._headline, curses.A_BOLD)
        if self.stats.fields_filter:
            regex = self.stats.fields_filter
            if len(regex) > MAX_REGEX_LEN:
                regex = regex[:MAX_REGEX_LEN] + '...'
            self.screen.addstr(1, 17, 'regex filter: {0}'.format(regex))
        if self._display_guests:
            col_name = 'Guest Name'
        else:
            col_name = 'Event'
        self.screen.addstr(2, 1, '%-40s %10s%7s %8s' %
                           (col_name, 'Total', '%Total', 'CurAvg/s'),
                           curses.A_STANDOUT)
        self.screen.addstr(4, 1, 'Collecting data...')
        self.screen.refresh()

    def _refresh_body(self, sleeptime):
        def insert_child(sorted_items, child, values, parent):
            num = len(sorted_items)
            for i in range(0, num):
                # only add child if parent is present
                if parent.startswith(sorted_items[i][0]):
                    sorted_items.insert(i + 1, ('  ' + child, values))

        def get_sorted_events(self, stats):
            """ separate parent and child events """
            if self._sorting == SORT_DEFAULT:
                def sortkey(pair):
                    # sort by (delta value, overall value)
                    v = pair[1]
                    return (v.delta, v.value)
            else:
                def sortkey(pair):
                    # sort by overall value
                    v = pair[1]
                    return v.value

            childs = []
            sorted_items = []
            # we can't rule out child events to appear prior to parents even
            # when sorted - separate out all children first, and add in later
            for key, values in sorted(stats.items(), key=sortkey,
                                      reverse=True):
                if values == (0, 0):
                    continue
                if key.find(' ') != -1:
                    if not self.stats.child_events:
                        continue
                    childs.insert(0, (key, values))
                else:
                    sorted_items.append((key, values))
            if self.stats.child_events:
                for key, values in childs:
                    (child, parent) = key.split(' ')
                    insert_child(sorted_items, child, values, parent)

            return sorted_items

        if not self._is_running_guest(self.stats.pid_filter):
            if self._gname:
                try: # ...to identify the guest by name in case it's back
                    pids = self.get_pid_from_gname(self._gname)
                    if len(pids) == 1:
                        self._refresh_header(pids[0])
                        self._update_pid(pids[0])
                        return
                except:
                    pass
            self._display_guest_dead()
            # leave final data on screen
            return
        row = 3
        self.screen.move(row, 0)
        self.screen.clrtobot()
        stats = self.stats.get(self._display_guests)
        total = 0.
        ctotal = 0.
        for key, values in stats.items():
            if self._display_guests:
                if self.get_gname_from_pid(key):
                    total += values.value
                continue
            if not key.find(' ') != -1:
                total += values.value
            else:
                ctotal += values.value
        if total == 0.:
            # we don't have any fields, or all non-child events are filtered
            total = ctotal

        # print events
        tavg = 0
        tcur = 0
        guest_removed = False
        for key, values in get_sorted_events(self, stats):
            if row >= self.screen.getmaxyx()[0] - 1 or values == (0, 0):
                break
            if self._display_guests:
                key = self.get_gname_from_pid(key)
                if not key:
                    continue
            cur = int(round(values.delta / sleeptime)) if values.delta else 0
            if cur < 0:
                guest_removed = True
                continue
            if key[0] != ' ':
                if values.delta:
                    tcur += values.delta
                ptotal = values.value
                ltotal = total
            else:
                ltotal = ptotal
            self.screen.addstr(row, 1, '%-40s %10d%7.1f %8s' % (key,
                               values.value,
                               values.value * 100 / float(ltotal), cur))
            row += 1
        if row == 3:
            if guest_removed:
                self.screen.addstr(4, 1, 'Guest removed, updating...')
            else:
                self.screen.addstr(4, 1, 'No matching events reported yet')
        if row > 4:
            tavg = int(round(tcur / sleeptime)) if tcur > 0 else ''
            self.screen.addstr(row, 1, '%-40s %10d        %8s' %
                               ('Total', total, tavg), curses.A_BOLD)
        self.screen.refresh()

    def _display_guest_dead(self):
        marker = '   Guest is DEAD   '
        y = min(len(self._headline), 80 - len(marker))
        self.screen.addstr(0, y, marker, curses.A_BLINK | curses.A_STANDOUT)

    def _show_msg(self, text):
        """Display message centered text and exit on key press"""
        hint = 'Press any key to continue'
        curses.cbreak()
        self.screen.erase()
        (x, term_width) = self.screen.getmaxyx()
        row = 2
        for line in text:
            start = (term_width - len(line)) // 2
            self.screen.addstr(row, start, line)
            row += 1
        self.screen.addstr(row + 1, (term_width - len(hint)) // 2, hint,
                           curses.A_STANDOUT)
        self.screen.getkey()

    def _show_help_interactive(self):
        """Display help with list of interactive commands"""
        msg = ('   b     toggle events by guests (debugfs only, honors'
               ' filters)',
               '   c     clear filter',
               '   f     filter by regular expression',
               '   g     filter by guest name/PID',
               '   h     display interactive commands reference',
               '   o     toggle sorting order (Total vs CurAvg/s)',
               '   p     filter by guest name/PID',
               '   q     quit',
               '   r     reset stats',
               '   s     set update interval',
               '   x     toggle reporting of stats for individual child trace'
               ' events',
               'Any other key refreshes statistics immediately')
        curses.cbreak()
        self.screen.erase()
        self.screen.addstr(0, 0, "Interactive commands reference",
                           curses.A_BOLD)
        self.screen.addstr(2, 0, "Press any key to exit", curses.A_STANDOUT)
        row = 4
        for line in msg:
            self.screen.addstr(row, 0, line)
            row += 1
        self.screen.getkey()
        self._refresh_header()

    def _show_filter_selection(self):
        """Draws filter selection mask.

        Asks for a valid regex and sets the fields filter accordingly.

        """
        msg = ''
        while True:
            self.screen.erase()
            self.screen.addstr(0, 0,
                               "Show statistics for events matching a regex.",
                               curses.A_BOLD)
            self.screen.addstr(2, 0,
                               "Current regex: {0}"
                               .format(self.stats.fields_filter))
            self.screen.addstr(5, 0, msg)
            self.screen.addstr(3, 0, "New regex: ")
            curses.echo()
            regex = self.screen.getstr().decode(ENCODING)
            curses.noecho()
            if len(regex) == 0:
                self.stats.fields_filter = ''
                self._refresh_header()
                return
            try:
                re.compile(regex)
                self.stats.fields_filter = regex
                self._refresh_header()
                return
            except re.error:
                msg = '"' + regex + '": Not a valid regular expression'
                continue

    def _show_set_update_interval(self):
        """Draws update interval selection mask."""
        msg = ''
        while True:
            self.screen.erase()
            self.screen.addstr(0, 0, 'Set update interval (defaults to %.1fs).' %
                               DELAY_DEFAULT, curses.A_BOLD)
            self.screen.addstr(4, 0, msg)
            self.screen.addstr(2, 0, 'Change delay from %.1fs to ' %
                               self._delay_regular)
            curses.echo()
            val = self.screen.getstr().decode(ENCODING)
            curses.noecho()

            try:
                if len(val) > 0:
                    delay = float(val)
                    if delay < 0.1:
                        msg = '"' + str(val) + '": Value must be >=0.1'
                        continue
                    if delay > 25.5:
                        msg = '"' + str(val) + '": Value must be <=25.5'
                        continue
                else:
                    delay = DELAY_DEFAULT
                self._delay_regular = delay
                break

            except ValueError:
                msg = '"' + str(val) + '": Invalid value'
        self._refresh_header()

    def _is_running_guest(self, pid):
        """Check if pid is still a running process."""
        if not pid:
            return True
        return os.path.isdir(os.path.join('/proc/', str(pid)))

    def _show_vm_selection_by_guest(self):
        """Draws guest selection mask.

        Asks for a guest name or pid until a valid guest name or '' is entered.

        """
        msg = ''
        while True:
            self.screen.erase()
            self.screen.addstr(0, 0,
                               'Show statistics for specific guest or pid.',
                               curses.A_BOLD)
            self.screen.addstr(1, 0,
                               'This might limit the shown data to the trace '
                               'statistics.')
            self.screen.addstr(5, 0, msg)
            self._print_all_gnames(7)
            curses.echo()
            curses.curs_set(1)
            self.screen.addstr(3, 0, "Guest or pid [ENTER exits]: ")
            guest = self.screen.getstr().decode(ENCODING)
            curses.noecho()

            pid = 0
            if not guest or guest == '0':
                break
            if guest.isdigit():
                if not self._is_running_guest(guest):
                    msg = '"' + guest + '": Not a running process'
                    continue
                pid = int(guest)
                break
            pids = []
            try:
                pids = self.get_pid_from_gname(guest)
            except:
                msg = '"' + guest + '": Internal error while searching, ' \
                      'use pid filter instead'
                continue
            if len(pids) == 0:
                msg = '"' + guest + '": Not an active guest'
                continue
            if len(pids) > 1:
                msg = '"' + guest + '": Multiple matches found, use pid ' \
                      'filter instead'
                continue
            pid = pids[0]
            break
        curses.curs_set(0)
        self._refresh_header(pid)
        self._update_pid(pid)

    def show_stats(self):
        """Refreshes the screen and processes user input."""
        sleeptime = self._delay_initial
        self._refresh_header()
        start = 0.0  # result based on init value never appears on screen
        while True:
            self._refresh_body(time.time() - start)
            curses.halfdelay(int(sleeptime * 10))
            start = time.time()
            sleeptime = self._delay_regular
            try:
                char = self.screen.getkey()
                if char == 'b':
                    self._display_guests = not self._display_guests
                    if self.stats.toggle_display_guests(self._display_guests):
                        self._show_msg(['Command not available with '
                                        'tracepoints enabled', 'Restart with '
                                        'debugfs only (see option \'-d\') and '
                                        'try again!'])
                        self._display_guests = not self._display_guests
                    self._refresh_header()
                if char == 'c':
                    self.stats.fields_filter = ''
                    self._refresh_header(0)
                    self._update_pid(0)
                if char == 'f':
                    curses.curs_set(1)
                    self._show_filter_selection()
                    curses.curs_set(0)
                    sleeptime = self._delay_initial
                if char == 'g' or char == 'p':
                    self._show_vm_selection_by_guest()
                    sleeptime = self._delay_initial
                if char == 'h':
                    self._show_help_interactive()
                if char == 'o':
                    self._sorting = not self._sorting
                if char == 'q':
                    break
                if char == 'r':
                    self.stats.reset()
                if char == 's':
                    curses.curs_set(1)
                    self._show_set_update_interval()
                    curses.curs_set(0)
                    sleeptime = self._delay_initial
                if char == 'x':
                    self.stats.child_events = not self.stats.child_events
            except KeyboardInterrupt:
                break
            except curses.error:
                continue


def batch(stats):
    """Prints statistics in a key, value format."""
    try:
        s = stats.get()
        time.sleep(1)
        s = stats.get()
        for key, values in sorted(s.items()):
            print('%-42s%10d%10d' % (key.split(' ')[0], values.value,
                  values.delta))
    except KeyboardInterrupt:
        pass


def log(stats):
    """Prints statistics as reiterating key block, multiple value blocks."""
    keys = sorted(stats.get().keys())

    def banner():
        for key in keys:
            print(key.split(' ')[0], end=' ')
        print()

    def statline():
        s = stats.get()
        for key in keys:
            print(' %9d' % s[key].delta, end=' ')
        print()
    line = 0
    banner_repeat = 20
    while True:
        try:
            time.sleep(1)
            if line % banner_repeat == 0:
                banner()
            statline()
            line += 1
        except KeyboardInterrupt:
            break


def get_options():
    """Returns processed program arguments."""
    description_text = """
This script displays various statistics about VMs running under KVM.
The statistics are gathered from the KVM debugfs entries and / or the
currently available perf traces.

The monitoring takes additional cpu cycles and might affect the VM's
performance.

Requirements:
- Access to:
    %s
    %s/events/*
    /proc/pid/task
- /proc/sys/kernel/perf_event_paranoid < 1 if user has no
  CAP_SYS_ADMIN and perf events are used.
- CAP_SYS_RESOURCE if the hard limit is not high enough to allow
  the large number of files that are possibly opened.

Interactive Commands:
   b     toggle events by guests (debugfs only, honors filters)
   c     clear filter
   f     filter by regular expression
   g     filter by guest name
   h     display interactive commands reference
   o     toggle sorting order (Total vs CurAvg/s)
   p     filter by PID
   q     quit
   r     reset stats
   s     set update interval
   x     toggle reporting of stats for individual child trace events
Press any other key to refresh statistics immediately.
""" % (PATH_DEBUGFS_KVM, PATH_DEBUGFS_TRACING)

    class PlainHelpFormatter(optparse.IndentedHelpFormatter):
        def format_description(self, description):
            if description:
                return description + "\n"
            else:
                return ""

    def cb_guest_to_pid(option, opt, val, parser):
        try:
            pids = Tui.get_pid_from_gname(val)
        except:
            sys.exit('Error while searching for guest "{}". Use "-p" to '
                     'specify a pid instead?'.format(val))
        if len(pids) == 0:
            sys.exit('Error: No guest by the name "{}" found'.format(val))
        if len(pids) > 1:
            sys.exit('Error: Multiple processes found (pids: {}). Use "-p" '
                     'to specify the desired pid'.format(" ".join(pids)))
        parser.values.pid = pids[0]

    optparser = optparse.OptionParser(description=description_text,
                                      formatter=PlainHelpFormatter())
    optparser.add_option('-1', '--once', '--batch',
                         action='store_true',
                         default=False,
                         dest='once',
                         help='run in batch mode for one second',
                         )
    optparser.add_option('-i', '--debugfs-include-past',
                         action='store_true',
                         default=False,
                         dest='dbgfs_include_past',
                         help='include all available data on past events for '
                              'debugfs',
                         )
    optparser.add_option('-l', '--log',
                         action='store_true',
                         default=False,
                         dest='log',
                         help='run in logging mode (like vmstat)',
                         )
    optparser.add_option('-t', '--tracepoints',
                         action='store_true',
                         default=False,
                         dest='tracepoints',
                         help='retrieve statistics from tracepoints',
                         )
    optparser.add_option('-d', '--debugfs',
                         action='store_true',
                         default=False,
                         dest='debugfs',
                         help='retrieve statistics from debugfs',
                         )
    optparser.add_option('-f', '--fields',
                         action='store',
                         default='',
                         dest='fields',
                         help='''fields to display (regex)
                                 "-f help" for a list of available events''',
                         )
    optparser.add_option('-p', '--pid',
                         action='store',
                         default=0,
                         type='int',
                         dest='pid',
                         help='restrict statistics to pid',
                         )
    optparser.add_option('-g', '--guest',
                         action='callback',
                         type='string',
                         dest='pid',
                         metavar='GUEST',
                         help='restrict statistics to guest by name',
                         callback=cb_guest_to_pid,
                         )
    options, unkn = optparser.parse_args(sys.argv)
    if len(unkn) != 1:
        sys.exit('Error: Extra argument(s): ' + ' '.join(unkn[1:]))
    try:
        # verify that we were passed a valid regex up front
        re.compile(options.fields)
    except re.error:
        sys.exit('Error: "' + options.fields + '" is not a valid regular '
                 'expression')

    return options


def check_access(options):
    """Exits if the current user can't access all needed directories."""
    if not os.path.exists(PATH_DEBUGFS_TRACING) and (options.tracepoints or
                                                     not options.debugfs):
        sys.stderr.write("Please enable CONFIG_TRACING in your kernel "
                         "when using the option -t (default).\n"
                         "If it is enabled, make {0} readable by the "
                         "current user.\n"
                         .format(PATH_DEBUGFS_TRACING))
        if options.tracepoints:
            sys.exit(1)

        sys.stderr.write("Falling back to debugfs statistics!\n")
        options.debugfs = True
        time.sleep(5)

    return options


def assign_globals():
    global PATH_DEBUGFS_KVM
    global PATH_DEBUGFS_TRACING

    debugfs = ''
    for line in open('/proc/mounts'):
        if line.split(' ')[0] == 'debugfs':
            debugfs = line.split(' ')[1]
            break
    if debugfs == '':
        sys.stderr.write("Please make sure that CONFIG_DEBUG_FS is enabled in "
                         "your kernel, mounted and\nreadable by the current "
                         "user:\n"
                         "('mount -t debugfs debugfs /sys/kernel/debug')\n")
        sys.exit(1)

    PATH_DEBUGFS_KVM = os.path.join(debugfs, 'kvm')
    PATH_DEBUGFS_TRACING = os.path.join(debugfs, 'tracing')

    if not os.path.exists(PATH_DEBUGFS_KVM):
        sys.stderr.write("Please make sure that CONFIG_KVM is enabled in "
                         "your kernel and that the modules are loaded.\n")
        sys.exit(1)


def main():
    assign_globals()
    options = get_options()
    options = check_access(options)

    if (options.pid > 0 and
        not os.path.isdir(os.path.join('/proc/',
                                       str(options.pid)))):
        sys.stderr.write('Did you use a (unsupported) tid instead of a pid?\n')
        sys.exit('Specified pid does not exist.')

    stats = Stats(options)

    if options.fields == 'help':
        stats.fields_filter = None
        event_list = []
        for key in stats.get().keys():
            event_list.append(key.split('(', 1)[0])
        sys.stdout.write('  ' + '\n  '.join(sorted(set(event_list))) + '\n')
        sys.exit(0)

    if options.log:
        log(stats)
    elif not options.once:
        with Tui(stats) as tui:
            tui.show_stats()
    else:
        batch(stats)

if __name__ == "__main__":
    main()
