#!/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 tapset_env(tapset_dir):
    tenv = copy.copy(os.environ)
    tenv["SYSTEMTAP_TAPSET"] = tapset_dir
    return tenv

def cmd_run(args):
    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"]
    if args.pid is not None:
        stapargs.extend(["-x", args.pid])
    stapargs.extend(["-e", script])
    subprocess.call(stapargs, env=tapset_env(tapsets))


def cmd_list(args):
    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", "-l", script],
                                stdout=subprocess.PIPE,
                                universal_newlines=True,
                                env=tapset_env(tapsets))
        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()
