#!/usr/bin/env python

# Copyright (c) 2011 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Android system-wide tracing utility.

This is a tool for capturing a trace that includes data from both userland and
the kernel.  It creates an HTML file for visualizing the trace.
"""

# Make sure we're using a new enough version of Python.
# The flags= parameter of re.sub() is new in Python 2.7. And Systrace does not
# support Python 3 yet.

# pylint: disable=wrong-import-position
import sys

version = sys.version_info[:2]
if version != (2, 7):
  sys.stderr.write('This script does not support Python %d.%d. '
                   'Please use Python 2.7.\n' % version)
  sys.exit(1)


import optparse
import os
import time

_SYSTRACE_DIR = os.path.abspath(
    os.path.join(os.path.dirname(__file__), os.path.pardir))
_CATAPULT_DIR = os.path.join(
    os.path.dirname(os.path.abspath(__file__)), os.path.pardir, os.path.pardir)
_DEVIL_DIR = os.path.join(_CATAPULT_DIR, 'devil')
if _DEVIL_DIR not in sys.path:
  sys.path.insert(0, _DEVIL_DIR)
if _SYSTRACE_DIR not in sys.path:
  sys.path.insert(0, _SYSTRACE_DIR)

from devil import devil_env
from devil.android.sdk import adb_wrapper
from systrace import systrace_runner
from systrace import util
from systrace.tracing_agents import atrace_agent
from systrace.tracing_agents import atrace_from_file_agent
from systrace.tracing_agents import atrace_process_dump
from systrace.tracing_agents import ftrace_agent
from systrace.tracing_agents import walt_agent


ALL_MODULES = [atrace_agent, atrace_from_file_agent, atrace_process_dump,
               ftrace_agent, walt_agent]


def parse_options(argv):
  """Parses and checks the command-line options.

  Returns:
    A tuple containing the options structure and a list of categories to
    be traced.
  """
  usage = 'Usage: %prog [options] [category1 [category2 ...]]'
  desc = 'Example: %prog -b 32768 -t 15 gfx input view sched freq'
  parser = optparse.OptionParser(usage=usage, description=desc,
                                 conflict_handler='resolve')
  parser = util.get_main_options(parser)

  parser.add_option('-l', '--list-categories', dest='list_categories',
                    default=False, action='store_true',
                    help='list the available categories and exit')

  # Add the other agent parsing options to the parser. For Systrace on the
  # command line, all agents are added. For Android, only the compatible agents
  # will be added.
  for module in ALL_MODULES:
    option_group = module.add_options(parser)
    if option_group:
      parser.add_option_group(option_group)

  options, categories = parser.parse_args(argv[1:])

  if options.output_file is None:
    base = 'trace'
    if options.from_file is not None:
      base = os.path.splitext(options.from_file)[0]
    suffix = '.json' if options.write_json else '.html'
    options.output_file = base + suffix

  if options.link_assets or options.asset_dir != 'trace-viewer':
    parser.error('--link-assets and --asset-dir are deprecated.')

  if options.trace_time and options.trace_time < 0:
    parser.error('the trace time must be a non-negative number')

  if (options.trace_buf_size is not None) and (options.trace_buf_size <= 0):
    parser.error('the trace buffer size must be a positive number')

  return (options, categories)

def find_adb():
  """Finds adb on the path.

  This method is provided to avoid the issue of diskutils.spawn's
  find_executable which first searches the current directory before
  searching $PATH. That behavior results in issues where systrace.py
  uses a different adb than the one in the path.
  """
  paths = os.environ['PATH'].split(os.pathsep)
  executable = 'adb'
  if sys.platform == 'win32':
    executable = executable + '.exe'
  for p in paths:
    f = os.path.join(p, executable)
    if os.path.isfile(f):
      return f
  return None

def initialize_devil():
  """Initialize devil to use adb from $PATH"""
  adb_path = find_adb()
  if adb_path is None:
    print >> sys.stderr, "Unable to find adb, is it in your path?"
    sys.exit(1)
  devil_dynamic_config = {
    'config_type': 'BaseConfig',
    'dependencies': {
      'adb': {
        'file_info': {
          devil_env.GetPlatform(): {
            'local_paths': [os.path.abspath(adb_path)]
          }
        }
      }
    }
  }
  devil_env.config.Initialize(configs=[devil_dynamic_config])


def main_impl(arguments):
  # Parse the command line options.
  options, categories = parse_options(arguments)

  # Override --atrace-categories and --ftrace-categories flags if command-line
  # categories are provided.
  if categories:
    if options.target == 'android':
      options.atrace_categories = categories
    elif options.target == 'linux':
      options.ftrace_categories = categories
    else:
      raise RuntimeError('Categories are only valid for atrace/ftrace. Target '
                         'platform must be either Android or Linux.')

  # Include atrace categories by default in Systrace.
  if options.target == 'android' and not options.atrace_categories:
    options.atrace_categories = atrace_agent.DEFAULT_CATEGORIES

  if options.target == 'android' and not options.from_file:
    initialize_devil()
    devices = [a.GetDeviceSerial() for a in adb_wrapper.AdbWrapper.Devices()]
    if not options.device_serial_number:
      if len(devices) == 0:
        raise RuntimeError('No ADB devices connected.')
      elif len(devices) >= 2:
        raise RuntimeError('Multiple devices connected, serial number required')
      options.device_serial_number = devices[0]
    elif options.device_serial_number not in devices:
      raise RuntimeError('Device with the serial number "%s" is not connected.'
                         % options.device_serial_number)

  # If list_categories is selected, just print the list of categories.
  # In this case, use of the tracing controller is not necessary.
  if options.list_categories:
    if options.target == 'android':
      atrace_agent.list_categories(options)
    elif options.target == 'linux':
      ftrace_agent.list_categories(options)
    return

  # Set up the systrace runner and start tracing.
  controller = systrace_runner.SystraceRunner(
      os.path.dirname(os.path.abspath(__file__)), options)
  controller.StartTracing()

  # Wait for the given number of seconds or until the user presses enter.
  # pylint: disable=superfluous-parens
  # (need the parens so no syntax error if trying to load with Python 3)
  if options.from_file is not None:
    print('Reading results from file.')
  elif options.trace_time:
    print('Starting tracing (%d seconds)' % options.trace_time)
    time.sleep(options.trace_time)
  else:
    raw_input('Starting tracing (stop with enter)')

  # Stop tracing and collect the output.
  print('Tracing completed. Collecting output...')
  controller.StopTracing()
  print('Outputting Systrace results...')
  controller.OutputSystraceResults(write_json=options.write_json)

def main():
  main_impl(sys.argv)

if __name__ == '__main__' and __package__ is None:
  main()
