#!/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, encoding='latin1') 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:]))
