# Lint as: python2, python3
"""
OProfile is a system-wide profiler for Linux systems,
capable of profiling all running code at low overhead.
OProfile is released under the GNU GPL.

It consists of a kernel driver and a daemon for collecting sample data,
and several post-profiling tools for turning data into information.

More Info: http://oprofile.sourceforge.net/
Will need some libaries to compile. Do 'apt-get build-dep oprofile'
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import logging
import os, shutil, time

from autotest_lib.client.bin import utils, profiler
from autotest_lib.client.common_lib import error


class oprofile(profiler.profiler):
    version = 7
    setup_done = False

# Notes on whether to use the local copy or the builtin from source:
# local = None
#      Try to use source copy if it works, else use local
# local = False
#       Force use of the source copy
# local = True
#       Force use of the local copy

# http://prdownloads.sourceforge.net/oprofile/oprofile-0.9.4.tar.gz
    def setup(self, tarball='oprofile-0.9.4.tar.bz2', local=None,
              *args, **dargs):
        if local == True:
            return

        try:
            self.tarball = utils.unmap_url(self.bindir, tarball,
                                                    self.tmpdir)
            utils.extract_tarball_to_dir(self.tarball, self.srcdir)
            os.chdir(self.srcdir)

            patch = os.path.join(self.bindir,"oprofile-69455.patch")
            utils.system('patch -p1 < %s' % patch)
            utils.configure('--with-kernel-support --prefix=' + \
                                                    self.srcdir)
            utils.make('-j %d' % utils.count_cpus())
            utils.make('install')
        except:
            # Build from source failed.
            # But maybe can still use the local copy
            local_opcontrol = os.path.exists('/usr/bin/opcontrol')
            local_opreport = os.path.exists('/usr/bin/opreport')
            if local == False or not local_opcontrol or not local_opreport:
                raise error.AutotestError('No oprofile available')
        else:
            # if we managed to build, try again to pick binaries
            self._pick_binaries(True)


    def _setup_oprofile(self):
        setup = ' --setup'
        if not self.vmlinux:
            setup += ' --no-vmlinux'
        else:
            setup += ' --vmlinux=%s' % self.vmlinux
        for e in self.events:
            setup += ' --event=%s' % e
        if self.others:
            setup += ' ' + self.others


        utils.system(self.opcontrol + setup)
        self.setup_done = True


    def _pick_binaries(self, after_setup):
        src_opreport  = os.path.join(self.srcdir, 'bin/opreport')
        src_opcontrol = os.path.join(self.srcdir, 'bin/opcontrol')

        if (self.local == False and after_setup) or (
                (self.local in (None, False) and os.path.exists(src_opreport)
                 and os.path.exists(src_opcontrol))):
            print("Using source-built copy of oprofile")
            self.opreport = src_opreport
            self.opcontrol = src_opcontrol
            perform_setup = True
        elif not self.local and not after_setup:
            # if we are neither forced to use the local versions and
            # we're not running after setup() then delay the decision
            return
        else:
            print("Using machine local copy of oprofile")
            self.opreport = '/usr/bin/opreport'
            self.opcontrol = '/usr/bin/opcontrol'

        self._setup_oprofile()


    def initialize(self, vmlinux=None, events=[], others=None, local=None):
        self.job.require_gcc()

        if not vmlinux:
            self.vmlinux = utils.get_vmlinux()
        else:
            self.vmlinux = vmlinux
        if not len(events):
            self.events = ['default']
        else:
            self.events = events
        self.others = others
        self.local = local

        # If there is existing setup file, oprofile may fail to start with default parameters.
        if os.path.isfile('/root/.oprofile/daemonrc'):
            os.rename('/root/.oprofile/daemonrc', '/root/.oprofile/daemonrc.org')

        self._pick_binaries(False)


    def start(self, test):
        if not self.setup_done:
            self._pick_binaries(True)

        self.start_time = time.ctime()
        utils.system(self.opcontrol + ' --shutdown')
        utils.system(self.opcontrol + ' --reset')
        utils.system(self.opcontrol + ' --start')


    def stop(self, test):
        self.stop_time = time.ctime()
        utils.system(self.opcontrol + ' --stop')
        utils.system(self.opcontrol + ' --dump')


    def report(self, test):
        # Output kernel per-symbol profile report
        reportfile = test.profdir + '/oprofile.kernel'
        if self.vmlinux:
            report = self.opreport + ' -l ' + self.vmlinux
            if os.path.exists(utils.get_modules_dir()):
                report += ' -p ' + utils.get_modules_dir()
            logging.info('Starting oprofile: %s' % self.start_time)
            utils.system(report + ' > ' + reportfile)
            logging.info('Ending oprofile: %s' % self.stop_time)

        else:
            utils.system("echo 'no vmlinux found.' > %s" % reportfile)

        # output profile summary report
        reportfile = test.profdir + '/oprofile.user'
        logging.info('Starting oprofile: %s' % self.start_time)
        utils.system(self.opreport + ' --long-filenames ' + ' >> ' + reportfile)
        logging.info('Ending oprofile: %s' % self.stop_time)

        utils.system(self.opcontrol + ' --shutdown')
