"""
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'
"""
import os, shutil, time
from autotest_lib.client.bin import utils, profiler
from autotest_lib.client.common_lib import error
import logging

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')
