#!/usr/bin/env python

# Copyright 2017 The Fuchsia Authors
#
# Use of this source code is governed by a MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT

"""

This tool will color the lines from loglistener

Example usage #1:
  # Colorize log lines, with all messages from the same thread in the same color
  loglistener | scripts/colorize_logs -t

Example usage #2:
  # Colorize log lines, with all messages from the same process in the same color
  loglistener | scripts/colorize_logs

Example usage #3:
  # Print the colorization of log.txt to stdout
  # Identical to `scripts/colorize_logs < log.txt`
  scripts/colorize_logs log.txt

Example usage #4:
  # Colorize all ERROR and INFO lines in log.txt
  scripts/colorize_logs -r ERROR -r INFO log.txt

Example usage #5:
  # Colorize all lines with drv='<something>' in log.txt with distinct colors
  # for each <something>
  scripts/colorize_logs -r "drv='[^']*'" log.txt

"""

import argparse
import re
import sys

BASE_COLORS = [
    #'\033[40m', # black
    '\033[91m', # red
    '\033[92m', # green
    '\033[93m', # yellow
    '\033[94m', # blue
    '\033[95m', # magenta
    '\033[66m', # cyan
    #'\033[47m', # white
]
RESET_BG = '\033[49m'
RESET_FG = '\033[39m'

class ColorAssigner(object):
  def __init__(self, colors):
    self.lru = list(colors)
    self.task_colors = { }

  def get_bg_color(self, task_id):
    if task_id not in self.task_colors:
      c = self.lru.pop(0)
      self.task_colors[task_id] = c
    else:
      c = self.task_colors[task_id]
      self.lru.remove(c)

    self.lru.append(c)
    return c


PROCESS_RE = r'^\[\d+\.\d+] (\d+)[\.:]\d+> .*$'
THREAD_RE = r'^\[\d+\.\d+] (\d+[\.:]\d+)> .*$'

def main():
  parser = argparse.ArgumentParser(
      description=__doc__,
      formatter_class=argparse.RawDescriptionHelpFormatter)
  parser.add_argument("--process", "-p", dest="patterns", action="append_const",
                      const=PROCESS_RE, help="Color code by process (default)")
  parser.add_argument("--thread", "-t", dest="patterns", action="append_const",
                      const=THREAD_RE, help="Color code by thread")
  parser.add_argument("--regex", "-r", dest="patterns", action="append",
                      help="Color by matching regexp")
  parser.add_argument("input", nargs='?', action="store", default=None,
                      help="The file to colorize.  Defaults to stdin")
  args = parser.parse_args()

  if args.input:
    f = open(args.input, 'r')
  else:
    f = sys.stdin

  # If no patterns were specified, use the process pattern.
  if not args.patterns:
    args.patterns = [PROCESS_RE]

  # Define the identifier extractor.  It should be in group 1.
  patterns = []
  for pattern in args.patterns:
    regex = re.compile(pattern)
    if not regex.groups:
      # if there's no group, wrap the pattern
      regex = re.compile(r'^.*(' + pattern + r').*$')
    patterns.append(regex)

  assigner = ColorAssigner(BASE_COLORS);

  while True:
    line = f.readline()
    if not line:
      break

    line = line.strip()
    matched = False
    for line_re in patterns:
      m = line_re.match(line)
      if m:
        matched = True
        task_id = m.group(1)
        color = assigner.get_bg_color(task_id)

        # Use join to avoid python putting a space between each value being
        # printed.
        print ''.join([color, line, RESET_BG, RESET_FG])
        sys.stdout.flush()
        break

    if not matched:
      print line
      sys.stdout.flush()

if __name__ == '__main__':
  main()
