#!/usr/bin/python
# -*- 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/>.

from __future__ import print_function

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, 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()
