# Copyright (C) 2012 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the Google name nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import re
import itertools


class ProfilerFactory(object):

    @classmethod
    def create_profiler(cls, host, executable_path, output_dir, profiler_name=None, identifier=None):
        profilers = cls.profilers_for_platform(host.platform)
        if not profilers:
            return None
        profiler_name = profiler_name or cls.default_profiler_name(host.platform)
        profiler_class = next(itertools.ifilter(lambda profiler: profiler.name == profiler_name, profilers), None)
        if not profiler_class:
            return None
        return profilers[0](host, executable_path, output_dir, identifier)

    @classmethod
    def default_profiler_name(cls, platform):
        profilers = cls.profilers_for_platform(platform)
        return profilers[0].name if profilers else None

    @classmethod
    def profilers_for_platform(cls, platform):
        # GooglePProf requires TCMalloc/google-perftools, but is available everywhere.
        profilers_by_os_name = {
            'mac': [IProfiler, Sample, GooglePProf],
            'linux': [Perf, GooglePProf],
            # Note: freebsd, win32 have no profilers defined yet, thus --profile will be ignored
            # by default, but a profiler can be selected with --profiler=PROFILER explicitly.
        }
        return profilers_by_os_name.get(platform.os_name, [])


class Profiler(object):
    # Used by ProfilerFactory to lookup a profiler from the --profiler=NAME option.
    name = None

    def __init__(self, host, executable_path, output_dir, identifier=None):
        self._host = host
        self._executable_path = executable_path
        self._output_dir = output_dir
        self._identifier = identifier or 'test'
        self._host.filesystem.maybe_make_directory(self._output_dir)

    def adjusted_environment(self, env):
        return env

    def attach_to_pid(self, pid):
        pass

    def profile_after_exit(self):
        pass


class SingleFileOutputProfiler(Profiler):

    def __init__(self, host, executable_path, output_dir, output_suffix, identifier=None):
        super(SingleFileOutputProfiler, self).__init__(host, executable_path, output_dir, identifier)
        # FIXME: Currently all reports are kept as test.*, until we fix that, search up to 1000 names before giving up.
        self._output_path = self._find_unused_filename(self._output_dir, self._identifier, output_suffix)
        assert self._output_path

    def _find_unused_filename(self, directory, name, extension, search_limit=1000):
        for count in range(search_limit):
            if count:
                target_name = '%s-%s.%s' % (name, count, extension)
            else:
                target_name = '%s.%s' % (name, extension)
            target_path = self._host.filesystem.join(directory, target_name)
            if not self._host.filesystem.exists(target_path):
                return target_path
        # If we can't find an unused name in search_limit tries, just give up.
        return None


class GooglePProf(SingleFileOutputProfiler):
    name = 'pprof'

    def __init__(self, host, executable_path, output_dir, identifier=None):
        super(GooglePProf, self).__init__(host, executable_path, output_dir, 'pprof', identifier)

    def adjusted_environment(self, env):
        env['CPUPROFILE'] = self._output_path
        return env

    def _first_ten_lines_of_profile(self, pprof_output):
        match = re.search('^Total:[^\n]*\n((?:[^\n]*\n){0,10})', pprof_output, re.MULTILINE)
        return match.group(1) if match else None

    def _pprof_path(self):
        # FIXME: We should have code to find the right google-pprof executable, some Googlers have
        # google-pprof installed as "pprof" on their machines for them.
        return '/usr/bin/google-pprof'

    def profile_after_exit(self):
        # google-pprof doesn't check its arguments, so we have to.
        if not self._host.filesystem.exists(self._output_path):
            print 'Failed to gather profile, %s does not exist.' % self._output_path
            return

        pprof_args = [self._pprof_path(), '--text', self._executable_path, self._output_path]
        profile_text = self._host.executive.run_command(pprof_args)
        print 'First 10 lines of pprof --text:'
        print self._first_ten_lines_of_profile(profile_text)
        print 'http://google-perftools.googlecode.com/svn/trunk/doc/cpuprofile.html documents output.'
        print
        print 'To interact with the the full profile, including produce graphs:'
        print ' '.join([self._pprof_path(), self._executable_path, self._output_path])


class Perf(SingleFileOutputProfiler):
    name = 'perf'

    def __init__(self, host, executable_path, output_dir, identifier=None):
        super(Perf, self).__init__(host, executable_path, output_dir, 'data', identifier)
        self._perf_process = None
        self._pid_being_profiled = None

    def _perf_path(self):
        # FIXME: We may need to support finding the perf binary in other locations.
        return 'perf'

    def attach_to_pid(self, pid):
        assert not self._perf_process and not self._pid_being_profiled
        self._pid_being_profiled = pid
        cmd = [self._perf_path(), 'record', '--call-graph', '--pid', pid, '--output', self._output_path]
        self._perf_process = self._host.executive.popen(cmd)

    def _first_ten_lines_of_profile(self, perf_output):
        match = re.search('^#[^\n]*\n((?: [^\n]*\n){1,10})', perf_output, re.MULTILINE)
        return match.group(1) if match else None

    def profile_after_exit(self):
        # Perf doesn't automatically watch the attached pid for death notifications,
        # so we have to do it for it, and then tell it its time to stop sampling. :(
        self._host.executive.wait_limited(self._pid_being_profiled, limit_in_seconds=10)
        perf_exitcode = self._perf_process.poll()
        if perf_exitcode is None:  # This should always be the case, unless perf error'd out early.
            self._host.executive.interrupt(self._perf_process.pid)

        perf_exitcode = self._perf_process.wait()
        if perf_exitcode not in (0, -2):  # The exit code should always be -2, as we're always interrupting perf.
            print "'perf record' failed (exit code: %i), can't process results:" % perf_exitcode
            return

        perf_args = [self._perf_path(), 'report', '--call-graph', 'none', '--input', self._output_path]
        print "First 10 lines of 'perf report --call-graph=none':"

        print ' '.join(perf_args)
        perf_output = self._host.executive.run_command(perf_args)
        print self._first_ten_lines_of_profile(perf_output)

        print 'To view the full profile, run:'
        print ' '.join([self._perf_path(), 'report', '-i', self._output_path])
        print  # An extra line between tests looks nicer.


class Sample(SingleFileOutputProfiler):
    name = 'sample'

    def __init__(self, host, executable_path, output_dir, identifier=None):
        super(Sample, self).__init__(host, executable_path, output_dir, 'txt', identifier)
        self._profiler_process = None

    def attach_to_pid(self, pid):
        cmd = ['sample', pid, '-mayDie', '-file', self._output_path]
        self._profiler_process = self._host.executive.popen(cmd)

    def profile_after_exit(self):
        self._profiler_process.wait()


class IProfiler(SingleFileOutputProfiler):
    name = 'iprofiler'

    def __init__(self, host, executable_path, output_dir, identifier=None):
        super(IProfiler, self).__init__(host, executable_path, output_dir, 'dtps', identifier)
        self._profiler_process = None

    def attach_to_pid(self, pid):
        # FIXME: iprofiler requires us to pass the directory separately
        # from the basename of the file, with no control over the extension.
        fs = self._host.filesystem
        cmd = ['iprofiler', '-timeprofiler', '-a', pid,
               '-d', fs.dirname(self._output_path), '-o', fs.splitext(fs.basename(self._output_path))[0]]
        # FIXME: Consider capturing instead of letting instruments spam to stderr directly.
        self._profiler_process = self._host.executive.popen(cmd)

    def profile_after_exit(self):
        # It seems like a nicer user experience to wait on the profiler to exit to prevent
        # it from spewing to stderr at odd times.
        self._profiler_process.wait()
