#!/usr/bin/python
# Copyright (c) 2012 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.

""""Processes a log file and resolves IPC message identifiers.

Resolves IPC messages of the form [unknown type NNNNNN] to named IPC messages.

e.g. logfile containing

I/stderr  ( 3915): ipc 3915.3.1370207904 2147483647 S [unknown type 66372]

will be transformed to:

I/stderr  ( 3915): ipc 3915.3.1370207904 2147483647 S ViewMsg_SetCSSColors

In order to find the message header files efficiently, it requires that
Chromium is checked out using git.
"""

import optparse
import os
import re
import subprocess
import sys


def _SourceDir():
  """Get chromium's source directory."""
  return os.path.join(sys.path[0], '..')


def _ReadLines(f):
  """Read from file f and generate right-stripped lines."""
  for line in f:
    yield line.rstrip()


def _GetMsgStartTable():
  """Read MsgStart enumeration from ipc/ipc_message_utils.h.

  Determines the message type identifiers by reading.
  header file ipc/ipc_message_utils.h and looking for
  enum IPCMessageStart.  Assumes following code format in header file:
  enum IPCMessageStart {
     Type1MsgStart ...,
     Type2MsgStart,
  };

  Returns:
      A dictionary mapping StartName to enumeration value.
  """
  ipc_message_file = _SourceDir() + '/ipc/ipc_message_utils.h'
  ipc_message_lines = _ReadLines(open(ipc_message_file))
  is_msg_start = False
  count = 0
  msg_start_table = dict()
  for line in ipc_message_lines:
    if is_msg_start:
      if line.strip() == '};':
        break
      msgstart_index = line.find('MsgStart')
      msg_type = line[:msgstart_index] + 'MsgStart'
      msg_start_table[msg_type.strip()] = count
      count+=1
    elif line.strip() == 'enum IPCMessageStart {':
      is_msg_start = True

  return msg_start_table


def _FindMessageHeaderFiles():
  """Look through the source directory for *_messages.h."""
  os.chdir(_SourceDir())
  pipe = subprocess.Popen(['git', 'ls-files', '--', '*_messages.h'],
                          stdout=subprocess.PIPE)
  return _ReadLines(pipe.stdout)


def _GetMsgId(msg_start, line_number, msg_start_table):
  """Construct the meessage id given the msg_start and the line number."""
  hex_str = '%x%04x' % (msg_start_table[msg_start], line_number)
  return int(hex_str, 16)


def _ReadHeaderFile(f, msg_start_table, msg_map):
  """Read a header file and construct a map from message_id to message name."""
  msg_def_re = re.compile(
      '^IPC_(?:SYNC_)?MESSAGE_[A-Z0-9_]+\(([A-Za-z0-9_]+).*')
  msg_start_re = re.compile(
      '^\s*#define\s+IPC_MESSAGE_START\s+([a-zA-Z0-9_]+MsgStart).*')
  msg_start = None
  msg_name = None
  line_number = 0

  for line in f:
    line_number+=1
    match = re.match(msg_start_re, line)
    if match:
      msg_start = match.group(1)
      # print "msg_start = " + msg_start
    match = re.match(msg_def_re, line)
    if match:
      msg_name = match.group(1)
      # print "msg_name = " + msg_name
    if msg_start and msg_name:
      msg_id = _GetMsgId(msg_start, line_number, msg_start_table)
      msg_map[msg_id] = msg_name
  return msg_map


def _ResolveMsg(msg_type, msg_map):
  """Fully resolve a message type to a name."""
  if msg_type in msg_map:
    return msg_map[msg_type]
  else:
    return '[Unknown message %d (0x%x)]x' % (msg_type, msg_type)


def _ProcessLog(f, msg_map):
  """Read lines from f and resolve the IPC messages according to msg_map."""
  unknown_msg_re = re.compile('\[unknown type (\d+)\]')
  for line in f:
    line = line.rstrip()
    match = re.search(unknown_msg_re, line)
    if match:
      line = re.sub(unknown_msg_re,
                    _ResolveMsg(int(match.group(1)), msg_map),
                    line)
    print line


def _GetMsgMap():
  """Returns a dictionary mapping from message number to message name."""
  msg_start_table = _GetMsgStartTable()
  msg_map = dict()
  for header_file in _FindMessageHeaderFiles():
    _ReadHeaderFile(open(header_file),
                    msg_start_table,
                    msg_map)
  return msg_map


def main():
  """Processes one or more log files with IPC logging messages.

     Replaces '[unknown type NNNNNN]' with resolved
     IPC messages.

     Reads from standard input if no log files specified on the
     command line.
  """
  parser = optparse.OptionParser('usage: %prog [LOGFILE...]')
  (_, args) = parser.parse_args()

  msg_map = _GetMsgMap()
  log_files = args

  if log_files:
    for log_file in log_files:
      _ProcessLog(open(log_file), msg_map)
  else:
    _ProcessLog(sys.stdin, msg_map)


if __name__ == '__main__':
  main()
