#!/usr/bin/env python3
#
# Copyright 2012 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Shutdown adb_logcat_monitor and print accumulated logs.

To test, call './adb_logcat_printer.py <base_dir>' where
<base_dir> contains 'adb logcat -v threadtime' files named as
logcat_<deviceID>_<sequenceNum>

The script will print the files to out, and will combine multiple
logcats from a single device if there is overlap.

Additionally, if a <base_dir>/LOGCAT_MONITOR_PID exists, the script
will attempt to terminate the contained PID by sending a SIGINT and
monitoring for the deletion of the aforementioned file.
"""
# pylint: disable=W0702

import argparse
import io
import logging
import os
import re
import signal
import sys
import time


# Set this to debug for more verbose output
LOG_LEVEL = logging.INFO


def CombineLogFiles(list_of_lists, logger):
  """Splices together multiple logcats from the same device.

  Args:
    list_of_lists: list of pairs (filename, list of timestamped lines)
    logger: handler to log events

  Returns:
    list of lines with duplicates removed
  """
  cur_device_log = ['']
  for cur_file, cur_file_lines in list_of_lists:
    # Ignore files with just the logcat header
    if len(cur_file_lines) < 2:
      continue
    common_index = 0
    # Skip this step if list just has empty string
    if len(cur_device_log) > 1:
      try:
        line = cur_device_log[-1]
        # Used to make sure we only splice on a timestamped line
        if re.match(r'^\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3} ', line):
          common_index = cur_file_lines.index(line)
        else:
          logger.warning('splice error - no timestamp in "%s"?', line.strip())
      except ValueError:
        # The last line was valid but wasn't found in the next file
        cur_device_log += ['***** POSSIBLE INCOMPLETE LOGCAT *****']
        logger.info('Unable to splice %s. Incomplete logcat?', cur_file)

    cur_device_log += ['*'*30 + '  %s' % cur_file]
    cur_device_log.extend(cur_file_lines[common_index:])

  return cur_device_log


def FindLogFiles(base_dir):
  """Search a directory for logcat files.

  Args:
    base_dir: directory to search

  Returns:
    Mapping of device_id to a sorted list of file paths for a given device
  """
  logcat_filter = re.compile(r'^logcat_(\S+)_(\d+)$')
  # list of tuples (<device_id>, <seq num>, <full file path>)
  filtered_list = []
  for cur_file in os.listdir(base_dir):
    matcher = logcat_filter.match(cur_file)
    if matcher:
      filtered_list += [(matcher.group(1), int(matcher.group(2)),
                         os.path.join(base_dir, cur_file))]
  filtered_list.sort()
  file_map = {}
  for device_id, _, cur_file in filtered_list:
    if device_id not in file_map:
      file_map[device_id] = []

    file_map[device_id] += [cur_file]
  return file_map


def GetDeviceLogs(log_filenames, logger):
  """Read log files, combine and format.

  Args:
    log_filenames: mapping of device_id to sorted list of file paths
    logger: logger handle for logging events

  Returns:
    list of formatted device logs, one for each device.
  """
  device_logs = []

  for device, device_files in log_filenames.items():
    logger.debug('%s: %s', device, str(device_files))
    device_file_lines = []
    for cur_file in device_files:
      with open(cur_file) as f:
        device_file_lines += [(cur_file, f.read().splitlines())]
    combined_lines = CombineLogFiles(device_file_lines, logger)
    # Prepend each line with a short unique ID so it's easy to see
    # when the device changes.  We don't use the start of the device
    # ID because it can be the same among devices.  Example lines:
    # AB324:  foo
    # AB324:  blah
    device_logs += [('\n' + device[-5:] + ':  ').join(combined_lines)]
  return device_logs


def ShutdownLogcatMonitor(base_dir, logger):
  """Attempts to shutdown adb_logcat_monitor and blocks while waiting."""
  try:
    monitor_pid_path = os.path.join(base_dir, 'LOGCAT_MONITOR_PID')
    with open(monitor_pid_path) as f:
      monitor_pid = int(f.readline())

    logger.info('Sending SIGTERM to %d', monitor_pid)
    os.kill(monitor_pid, signal.SIGTERM)
    i = 0
    while True:
      time.sleep(.2)
      if not os.path.exists(monitor_pid_path):
        return
      if not os.path.exists('/proc/%d' % monitor_pid):
        logger.warning('Monitor (pid %d) terminated uncleanly?', monitor_pid)
        return
      logger.info('Waiting for logcat process to terminate.')
      i += 1
      if i >= 10:
        logger.warning('Monitor pid did not terminate. Continuing anyway.')
        return

  except (ValueError, IOError, OSError):
    logger.exception('Error signaling logcat monitor - continuing')


def main(argv):
  parser = argparse.ArgumentParser()
  parser.add_argument(
      '--output-path',
      help='Output file path (if unspecified, prints to stdout)')
  parser.add_argument('log_dir')
  args = parser.parse_args(argv)
  base_dir = args.log_dir

  log_stringio = io.StringIO()
  logger = logging.getLogger('LogcatPrinter')
  logger.setLevel(LOG_LEVEL)
  sh = logging.StreamHandler(log_stringio)
  sh.setFormatter(logging.Formatter('%(asctime)-2s %(levelname)-8s'
                                    ' %(message)s'))
  logger.addHandler(sh)

  if args.output_path:
    if not os.path.exists(os.path.dirname(args.output_path)):
      logger.warning('Output dir %s doesn\'t exist. Creating it.',
                     os.path.dirname(args.output_path))
      os.makedirs(os.path.dirname(args.output_path))
    output_file = open(args.output_path, 'w')
    logger.info(
        'Dumping logcat to local file %s. If running in a build, '
        'this file will likely will be uploaded to google storage '
        'in a later step. It can be downloaded from there.', args.output_path)
  else:
    output_file = sys.stdout

  try:
    # Wait at least 5 seconds after base_dir is created before printing.
    #
    # The idea is that 'adb logcat > file' output consists of 2 phases:
    #  1 Dump all the saved logs to the file
    #  2 Stream log messages as they are generated
    #
    # We want to give enough time for phase 1 to complete.  There's no
    # good method to tell how long to wait, but it usually only takes a
    # second.  On most bots, this code path won't occur at all, since
    # adb_logcat_monitor.py command will have spawned more than 5 seconds
    # prior to called this shell script.
    try:
      sleep_time = 5 - (time.time() - os.path.getctime(base_dir))
    except OSError:
      sleep_time = 5
    if sleep_time > 0:
      logger.warning('Monitor just started? Sleeping %.1fs', sleep_time)
      time.sleep(sleep_time)

    assert os.path.exists(base_dir), '%s does not exist' % base_dir
    ShutdownLogcatMonitor(base_dir, logger)
    separator = '\n' + '*' * 80 + '\n\n'
    for log in GetDeviceLogs(FindLogFiles(base_dir), logger):
      output_file.write(log)
      output_file.write(separator)
    with open(os.path.join(base_dir, 'eventlog')) as f:
      output_file.write('\nLogcat Monitor Event Log\n')
      output_file.write(f.read())
  except:
    logger.exception('Unexpected exception')

  logger.info('Done.')
  sh.flush()
  output_file.write('\nLogcat Printer Event Log\n')
  output_file.write(log_stringio.getvalue())

if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
