#!/usr/bin/env python2.6
#
# Copyright (C) 2011 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

#
# Remotely controls an OProfile session on an Android device.
#

import os
import sys
import subprocess
import getopt
import re
import shutil


# Find oprofile binaries (compiled on the host)
try:
  oprofile_bin_dir = os.environ['OPROFILE_BIN_DIR']
except:
  try:
    android_host_out = os.environ['ANDROID_HOST_OUT']
  except:
    print "Either OPROFILE_BIN_DIR or ANDROID_HOST_OUT must be set. Run \". envsetup.sh\" first"
    sys.exit(1)
  oprofile_bin_dir = os.path.join(android_host_out, 'bin')

opimport_bin = os.path.join(oprofile_bin_dir, 'opimport')
opreport_bin = os.path.join(oprofile_bin_dir, 'opreport')
opannotate_bin = os.path.join(oprofile_bin_dir, 'opannotate')


# Find symbol directories
try:
  android_product_out = os.environ['ANDROID_PRODUCT_OUT']
except:
  print "ANDROID_PRODUCT_OUT must be set. Run \". envsetup.sh\" first"
  sys.exit(1)

symbols_dir = os.path.join(android_product_out, 'symbols')
system_dir = os.path.join(android_product_out, 'system')


def execute(command, echo=True):
  if echo:
    print ' '.join(command)
  popen = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  output = ''
  while True:
    stdout, stderr = popen.communicate()
    if echo and len(stdout) != 0:
      print stdout
    if echo and len(stderr) != 0:
      print stderr
    output += stdout
    output += stderr
    rc = popen.poll()
    if rc is not None:
      break
  if echo:
    print 'exit code: %d' % rc
  return rc, output

# ADB wrapper
class Adb:
  def __init__(self, serial_number):
    self._base_args = ['adb']
    if serial_number != None:
      self._base_args.append('-s')
      self._base_args.append(serial_number)

  def shell(self, command_args, echo=True):
    return self._adb('shell', command_args, echo)

  def pull(self, source, dest, echo=True):
    return self._adb('pull', [source, dest], echo)

  def _adb(self, command, command_args, echo):
    return execute(self._base_args + [command] + command_args, echo)


# The tool program itself
class Tool:
  def __init__(self, argv):
    self.argv = argv
    self.verbose = False
    self.session_dir = '/tmp/oprofile'

  def usage(self):
    print "Usage: " + self.argv[0] + " [options] <command> [command args]"
    print
    print "  Options:"
    print
    print "    -h, --help            : show this help text"
    print "    -s, --serial=number   : the serial number of the device being profiled"
    print "    -v, --verbose         : show verbose output"
    print "    -d, --dir=path        : directory to store oprofile session on the host, default: /tmp/oprofile"
    print
    print "  Commands:"
    print
    print "    setup [args]          : setup profiler with specified arguments to 'opcontrol --setup'"
    print "      -t, --timer             : enable timer based profiling"
    print "      -e, --event=[spec]      : specify an event type to profile, eg. --event=CPU_CYCLES:100000"
    print "                                (not supported on all devices)"
    print "      -c, --callgraph=[depth] : specify callgraph capture depth, default is none"
    print "                                (not supported in timer mode)"
    print "      -k, --kernel-image      : specifies the location of a kernel image relative to the symbols directory"
    print "                                (and turns on kernel profiling). This need not be the same as the"
    print "                                location of the kernel on the actual device."
    print
    print "    shutdown              : shutdown profiler"
    print
    print "    start                 : start profiling"
    print
    print "    stop                  : stop profiling"
    print
    print "    status                : show profiler status"
    print
    print "    import                : dump samples and pull session directory from the device"
    print "      -f, --force             : remove existing session directory before import" 
    print
    print "    report [args]         : generate report with specified arguments to 'opreport'"
    print "      -l, --symbols           : show symbols"
    print "      -c, --callgraph         : show callgraph"
    print "      --help                  : show help for additional opreport options"
    print
    print "    annotate [args]       : generate annotation with specified arguments to 'annotation'"
    print "      -s, --source            : show source"
    print "      -a, --assembly          : show assembly"
    print "      --help                  : show help for additional opannotate options"
    print

  def main(self):
    rc = self.do_main()
    if rc == 2:
      print
      self.usage()
    return rc

  def do_main(self):
    try:
      opts, args = getopt.getopt(self.argv[1:],
        'hs:vd', ['help', 'serial=', 'dir=', 'verbose'])
    except getopt.GetoptError, e:
      print str(e)
      return 2

    serial_number = None
    for o, a in opts:
      if o in ('-h', '--help'):
        self.usage()
        return 0
      elif o in ('-s', '--serial'):
        serial_number = a
      elif o in ('-d', '--dir'):
        self.session_dir = a
      elif o in ('-v', '--verbose'):
        self.verbose = True

    if len(args) == 0:
      print '* A command must be specified.'
      return 2

    command = args[0]
    command_args = args[1:]

    self.adb = Adb(serial_number)

    if command == 'setup':
      rc = self.do_setup(command_args)
    elif command == 'shutdown':
      rc = self.do_shutdown(command_args)
    elif command == 'start':
      rc = self.do_start(command_args)
    elif command == 'stop':
      rc = self.do_stop(command_args)
    elif command == 'status':
      rc = self.do_status(command_args)
    elif command == 'import':
      rc = self.do_import(command_args)
    elif command == 'report':
      rc = self.do_report(command_args)
    elif command == 'annotate':
      rc = self.do_annotate(command_args)
    else:
      print '* Unknown command: ' + command
      return 2

    return rc

  def do_setup(self, command_args):
    events = []
    timer = False
    kernel = False
    kernel_image = ''
    callgraph = None

    try:
      opts, args = getopt.getopt(command_args,
        'te:c:k:', ['timer', 'event=', 'callgraph=', 'kernel='])
    except getopt.GetoptError, e:
      print '* Unsupported setup command arguments:', str(e)
      return 2

    for o, a in opts:
      if o in ('-t', '--timer'):
        timer = True
      elif o in ('-e', '--event'):
        events.append('--event=' + a)
      elif o in ('-c', '--callgraph'):
        callgraph = a
      elif o in ('-k', '--kernel'):
        kernel = True
        kernel_image = a

    if len(args) != 0:
      print '* Unsupported setup command arguments: %s' % (' '.join(args))
      return 2

    if not timer and len(events) == 0:
      print '* Must specify --timer or at least one --event argument.'
      return 2

    if timer and len(events) != 0:
      print '* --timer and --event cannot be used together.'
      return 2

    opcontrol_args = events
    if timer:
      opcontrol_args.append('--timer')
    if callgraph is not None:
      opcontrol_args.append('--callgraph=' + callgraph)
    if kernel and len(kernel_image) != 0:
      opcontrol_args.append('--vmlinux=' + kernel_image)

    # Get kernal VMA range.
    rc, output = self.adb.shell(['cat', '/proc/kallsyms'], echo=False)
    if rc != 0:
      print '* Failed to determine kernel VMA range.'
      print output
      return 1
    vma_start = re.search('([0-9a-fA-F]{8}) T _text', output).group(1)
    vma_end = re.search('([0-9a-fA-F]{8}) A _etext', output).group(1)

    # Setup the profiler.
    rc, output = self.adb.shell(['/system/xbin/opcontrol'] + self._opcontrol_verbose_arg() + [
      '--reset',
      '--kernel-range=' + vma_start + ',' + vma_end] + opcontrol_args + [
      '--setup',
      '--status', '--verbose-log=all'])
    if rc != 0:
      print '* Failed to setup profiler.'
      return 1
    return 0

  def do_shutdown(self, command_args):
    if len(command_args) != 0:
      print '* Unsupported shutdown command arguments: %s' % (' '.join(command_args))
      return 2

    rc, output = self.adb.shell(['/system/xbin/opcontrol'] + self._opcontrol_verbose_arg() + [
      '--shutdown'])
    if rc != 0:
      print '* Failed to shutdown.'
      return 1
    return 0

  def do_start(self, command_args):
    if len(command_args) != 0:
      print '* Unsupported start command arguments: %s' % (' '.join(command_args))
      return 2

    rc, output = self.adb.shell(['/system/xbin/opcontrol'] + self._opcontrol_verbose_arg() + [
      '--start', '--status'])
    if rc != 0:
      print '* Failed to start profiler.'
      return 1
    return 0

  def do_stop(self, command_args):
    if len(command_args) != 0:
      print '* Unsupported stop command arguments: %s' % (' '.join(command_args))
      return 2

    rc, output = self.adb.shell(['/system/xbin/opcontrol'] + self._opcontrol_verbose_arg() + [
      '--stop', '--status'])
    if rc != 0:
      print '* Failed to stop profiler.'
      return 1
    return 0

  def do_status(self, command_args):
    if len(command_args) != 0:
      print '* Unsupported status command arguments: %s' % (' '.join(command_args))
      return 2

    rc, output = self.adb.shell(['/system/xbin/opcontrol'] + self._opcontrol_verbose_arg() + [
      '--status'])
    if rc != 0:
      print '* Failed to get profiler status.'
      return 1
    return 0

  def do_import(self, command_args):
    force = False

    try:
      opts, args = getopt.getopt(command_args,
        'f', ['force'])
    except getopt.GetoptError, e:
      print '* Unsupported import command arguments:', str(e)
      return 2

    for o, a in opts:
      if o in ('-f', '--force'):
        force = True

    if len(args) != 0:
      print '* Unsupported import command arguments: %s' % (' '.join(args))
      return 2

    # Create session directory.
    print 'Creating session directory.'
    if os.path.exists(self.session_dir):
      if not force:
        print "* Session directory already exists: %s" % (self.session_dir)
        print "* Use --force to remove and recreate the session directory."
        return 1

      try:
        shutil.rmtree(self.session_dir)
      except e:
        print "* Failed to remove existing session directory: %s" % (self.session_dir)
        print e
        return 1

    try:
      os.makedirs(self.session_dir)
    except e:
      print "* Failed to create session directory: %s" % (self.session_dir)
      print e
      return 1

    raw_samples_dir = os.path.join(self.session_dir, 'raw_samples')
    samples_dir = os.path.join(self.session_dir, 'samples')
    abi_file = os.path.join(self.session_dir, 'abi')

    # Dump samples.
    print 'Dumping samples.'
    rc, output = self.adb.shell(['/system/xbin/opcontrol'] + self._opcontrol_verbose_arg() + [
      '--dump', '--status'])
    if rc != 0:
      print '* Failed to dump samples.'
      print output
      return 1

    # Pull samples.
    print 'Pulling samples from device.'
    rc, output = self.adb.pull('/data/oprofile/samples/', raw_samples_dir + '/', echo=False)
    if rc != 0:
      print '* Failed to pull samples from the device.'
      print output
      return 1

    # Pull ABI.
    print 'Pulling ABI information from device.'
    rc, output = self.adb.pull('/data/oprofile/abi', abi_file, echo=False)
    if rc != 0:
      print '* Failed to pull abi information from the device.'
      print output
      return 1

    # Invoke opimport on each sample file to convert it from the device ABI (ARM)
    # to the host ABI (x86).
    print 'Importing samples.'
    for dirpath, dirnames, filenames in os.walk(raw_samples_dir):
      for filename in filenames:
        if not re.match('^.*\.log$', filename):
          in_path = os.path.join(dirpath, filename)
          out_path = os.path.join(samples_dir, os.path.relpath(in_path, raw_samples_dir))
          out_dir = os.path.dirname(out_path)
          try:
            os.makedirs(out_dir)
          except e:
            print "* Failed to create sample directory: %s" % (out_dir)
            print e
            return 1

          rc, output = execute([opimport_bin, '-a', abi_file, '-o', out_path, in_path], echo=False)
          if rc != 0:
            print '* Failed to import samples.'
            print output
            return 1

    # Generate a short summary report.
    rc, output = self._execute_opreport([])
    if rc != 0:
      print '* Failed to generate summary report.'
      return 1
    return 0

  def do_report(self, command_args):
    rc, output = self._execute_opreport(command_args)
    if rc != 0:
      print '* Failed to generate report.'
      return 1
    return 0

  def do_annotate(self, command_args):
    rc, output = self._execute_opannotate(command_args)
    if rc != 0:
      print '* Failed to generate annotation.'
      return 1
    return 0

  def _opcontrol_verbose_arg(self):
    if self.verbose:
      return ['--verbose']
    else:
      return []

  def _execute_opreport(self, args):
    return execute([opreport_bin,
      '--session-dir=' + self.session_dir,
      '--image-path=' + symbols_dir + ',' + system_dir] + args)

  def _execute_opannotate(self, command_args):
    try:
      opts, args = getopt.getopt(command_args, 'sap:',
                                 ['source', 'assembly', 'help', 'image-path='])
    except getopt.GetoptError, e:
      print '* Unsupported opannotate command arguments:', str(e)
      return 2

    # Start with the default symbols directory
    symbols_dirs = symbols_dir

    anno_flag = []
    for o, a in opts:
      if o in ('-s', '--source'):
        anno_flag.append('-s')
      if o in ('-a', '--assembly'):
        anno_flag.append('-a')
        anno_flag.append('--objdump-params=-Cd')
      if o in ('--help'):
        anno_flag.append('--help')
      if o in ('p', '--image-path'):
        symbols_dirs = a + ',' + symbols_dir

    return execute([opannotate_bin,
      '--session-dir=' + self.session_dir,
      '--image-path=' + symbols_dirs + ',' + system_dir] + anno_flag + args)

# Main entry point
tool = Tool(sys.argv)
rc = tool.main()
sys.exit(rc)
