#!/usr/bin/env python3
# -*- python -*-
#
# Copyright (C) 2019 Red Hat, Inc
#
# QEMU SystemTap Trace Tool
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.

import argparse
import copy
import os.path
import re
import subprocess
import sys


def probe_prefix(binary):
    dirname, filename = os.path.split(binary)
    return re.sub("-", ".", filename) + ".log"


def which(binary):
    for path in os.environ["PATH"].split(os.pathsep):
        if os.path.exists(os.path.join(path, binary)):
                return os.path.join(path, binary)

    print("Unable to find '%s' in $PATH" % binary)
    sys.exit(1)


def tapset_dir(binary):
    dirname, filename = os.path.split(binary)
    if dirname == '':
        thisfile = which(binary)
    else:
        thisfile = os.path.realpath(binary)
        if not os.path.exists(thisfile):
            print("Unable to find '%s'" % thisfile)
            sys.exit(1)

    basedir = os.path.split(thisfile)[0]
    tapset = os.path.join(basedir, "..", "share", "systemtap", "tapset")
    return os.path.realpath(tapset)


def cmd_run(args):
    stap = which("stap")
    prefix = probe_prefix(args.binary)
    tapsets = tapset_dir(args.binary)

    if args.verbose:
        print("Using tapset dir '%s' for binary '%s'" % (tapsets, args.binary))

    probes = []
    for probe in args.probes:
        probes.append("probe %s.%s {}" % (prefix, probe))
    if len(probes) == 0:
        print("At least one probe pattern must be specified")
        sys.exit(1)

    script = " ".join(probes)
    if args.verbose:
        print("Compiling script '%s'" % script)
        script = """probe begin { print("Running script, <Ctrl>-c to quit\\n") } """ + script

    # We request an 8MB buffer, since the stap default 1MB buffer
    # can be easily overflowed by frequently firing QEMU traces
    stapargs = [stap, "-s", "8", "-I", tapsets ]
    if args.pid is not None:
        stapargs.extend(["-x", args.pid])
    stapargs.extend(["-e", script])
    subprocess.call(stapargs)


def cmd_list(args):
    stap = which("stap")
    tapsets = tapset_dir(args.binary)

    if args.verbose:
        print("Using tapset dir '%s' for binary '%s'" % (tapsets, args.binary))

    def print_probes(verbose, name):
        prefix = probe_prefix(args.binary)
        offset = len(prefix) + 1
        script = prefix + "." + name

        if verbose:
            print("Listing probes with name '%s'" % script)
        proc = subprocess.Popen([stap, "-I", tapsets, "-l", script],
                                stdout=subprocess.PIPE,
                                universal_newlines=True)
        out, err = proc.communicate()
        if proc.returncode != 0:
            print("No probes found, are the tapsets installed in %s" % tapset_dir(args.binary))
            sys.exit(1)

        for line in out.splitlines():
            if line.startswith(prefix):
                print("%s" % line[offset:])

    if len(args.probes) == 0:
        print_probes(args.verbose, "*")
    else:
        for probe in args.probes:
            print_probes(args.verbose, probe)


def main():
    parser = argparse.ArgumentParser(description="QEMU SystemTap trace tool")
    parser.add_argument("-v", "--verbose", help="Print verbose progress info",
                        action='store_true')

    subparser = parser.add_subparsers(help="commands")
    subparser.required = True
    subparser.dest = "command"

    runparser = subparser.add_parser("run", help="Run a trace session",
                                     formatter_class=argparse.RawDescriptionHelpFormatter,
                                     epilog="""

To watch all trace points on the qemu-system-x86_64 binary:

   %(argv0)s run qemu-system-x86_64

To only watch the trace points matching the qio* and qcrypto* patterns

   %(argv0)s run qemu-system-x86_64 'qio*' 'qcrypto*'
""" % {"argv0": sys.argv[0]})
    runparser.set_defaults(func=cmd_run)
    runparser.add_argument("--pid", "-p", dest="pid",
                           help="Restrict tracing to a specific process ID")
    runparser.add_argument("binary", help="QEMU system or user emulator binary")
    runparser.add_argument("probes", help="Probe names or wildcards",
                           nargs=argparse.REMAINDER)

    listparser = subparser.add_parser("list", help="List probe points",
                                      formatter_class=argparse.RawDescriptionHelpFormatter,
                                      epilog="""

To list all trace points on the qemu-system-x86_64 binary:

   %(argv0)s list qemu-system-x86_64

To only list the trace points matching the qio* and qcrypto* patterns

   %(argv0)s list qemu-system-x86_64 'qio*' 'qcrypto*'
""" % {"argv0": sys.argv[0]})
    listparser.set_defaults(func=cmd_list)
    listparser.add_argument("binary", help="QEMU system or user emulator binary")
    listparser.add_argument("probes", help="Probe names or wildcards",
                            nargs=argparse.REMAINDER)

    args = parser.parse_args()

    args.func(args)
    sys.exit(0)

if __name__ == '__main__':
    main()
