#!/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')


# 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

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

    if timer and callgraph is not None:
      print '* --callgraph cannot be used with --timer.'
      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 _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)

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