#!/usr/bin/env python
#
# Copyright 2013 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.
#
# Find the most recent tombstone file(s) on all connected devices
# and prints their stacks.
#
# Assumes tombstone file was created with current symbols.

import datetime
import multiprocessing
import os
import subprocess
import sys
import optparse

from pylib import android_commands
from pylib.device import device_utils


def _ListTombstones(device):
  """List the tombstone files on the device.

  Args:
    device: An instance of DeviceUtils.

  Yields:
    Tuples of (tombstone filename, date time of file on device).
  """
  lines = device.RunShellCommand('TZ=UTC su -c ls -a -l /data/tombstones')
  for line in lines:
    if 'tombstone' in line and not 'No such file or directory' in line:
      details = line.split()
      t = datetime.datetime.strptime(details[-3] + ' ' + details[-2],
                                     '%Y-%m-%d %H:%M')
      yield details[-1], t


def _GetDeviceDateTime(device):
  """Determine the date time on the device.

  Args:
    device: An instance of DeviceUtils.

  Returns:
    A datetime instance.
  """
  device_now_string = device.RunShellCommand('TZ=UTC date')
  return datetime.datetime.strptime(
      device_now_string[0], '%a %b %d %H:%M:%S %Z %Y')


def _GetTombstoneData(device, tombstone_file):
  """Retrieve the tombstone data from the device

  Args:
    device: An instance of DeviceUtils.
    tombstone_file: the tombstone to retrieve

  Returns:
    A list of lines
  """
  return device.old_interface.GetProtectedFileContents(
      '/data/tombstones/' + tombstone_file)


def _EraseTombstone(device, tombstone_file):
  """Deletes a tombstone from the device.

  Args:
    device: An instance of DeviceUtils.
    tombstone_file: the tombstone to delete.
  """
  return device.RunShellCommand(
      'rm /data/tombstones/' + tombstone_file, root=True)


def _ResolveSymbols(tombstone_data, include_stack):
  """Run the stack tool for given tombstone input.

  Args:
    tombstone_data: a list of strings of tombstone data.
    include_stack: boolean whether to include stack data in output.

  Yields:
    A string for each line of resolved stack output.
  """
  stack_tool = os.path.join(os.path.dirname(__file__), '..', '..',
                            'third_party', 'android_platform', 'development',
                            'scripts', 'stack')
  proc = subprocess.Popen(stack_tool, stdin=subprocess.PIPE,
                          stdout=subprocess.PIPE)
  output = proc.communicate(input='\n'.join(tombstone_data))[0]
  for line in output.split('\n'):
    if not include_stack and 'Stack Data:' in line:
      break
    yield line


def _ResolveTombstone(tombstone):
  lines = []
  lines += [tombstone['file'] + ' created on ' + str(tombstone['time']) +
            ', about this long ago: ' +
            (str(tombstone['device_now'] - tombstone['time']) +
            ' Device: ' + tombstone['serial'])]
  print '\n'.join(lines)
  print 'Resolving...'
  lines += _ResolveSymbols(tombstone['data'], tombstone['stack'])
  return lines


def _ResolveTombstones(jobs, tombstones):
  """Resolve a list of tombstones.

  Args:
    jobs: the number of jobs to use with multiprocess.
    tombstones: a list of tombstones.
  """
  if not tombstones:
    print 'No device attached?  Or no tombstones?'
    return
  if len(tombstones) == 1:
    data = _ResolveTombstone(tombstones[0])
  else:
    pool = multiprocessing.Pool(processes=jobs)
    data = pool.map(_ResolveTombstone, tombstones)
    data = ['\n'.join(d) for d in data]
  print '\n'.join(data)


def _GetTombstonesForDevice(device, options):
  """Returns a list of tombstones on a given device.

  Args:
    device: An instance of DeviceUtils.
    options: command line arguments from OptParse
  """
  ret = []
  all_tombstones = list(_ListTombstones(device))
  if not all_tombstones:
    print 'No device attached?  Or no tombstones?'
    return ret

  # Sort the tombstones in date order, descending
  all_tombstones.sort(cmp=lambda a, b: cmp(b[1], a[1]))

  # Only resolve the most recent unless --all-tombstones given.
  tombstones = all_tombstones if options.all_tombstones else [all_tombstones[0]]

  device_now = _GetDeviceDateTime(device)
  for tombstone_file, tombstone_time in tombstones:
    ret += [{'serial': device.old_interface.Adb().GetSerialNumber(),
             'device_now': device_now,
             'time': tombstone_time,
             'file': tombstone_file,
             'stack': options.stack,
             'data': _GetTombstoneData(device, tombstone_file)}]

  # Erase all the tombstones if desired.
  if options.wipe_tombstones:
    for tombstone_file, _ in all_tombstones:
      _EraseTombstone(device, tombstone_file)

  return ret

def main():
  parser = optparse.OptionParser()
  parser.add_option('--device',
                    help='The serial number of the device. If not specified '
                         'will use all devices.')
  parser.add_option('-a', '--all-tombstones', action='store_true',
                    help="""Resolve symbols for all tombstones, rather than just
                         the most recent""")
  parser.add_option('-s', '--stack', action='store_true',
                    help='Also include symbols for stack data')
  parser.add_option('-w', '--wipe-tombstones', action='store_true',
                    help='Erase all tombstones from device after processing')
  parser.add_option('-j', '--jobs', type='int',
                    default=4,
                    help='Number of jobs to use when processing multiple '
                         'crash stacks.')
  options, _ = parser.parse_args()

  if options.device:
    devices = [options.device]
  else:
    devices = android_commands.GetAttachedDevices()

  tombstones = []
  for device_serial in devices:
    device = device_utils.DeviceUtils(device_serial)
    tombstones += _GetTombstonesForDevice(device, options)

  _ResolveTombstones(options.jobs, tombstones)

if __name__ == '__main__':
  sys.exit(main())
