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

"""Watchlists

Watchlists is a mechanism that allow a developer (a "watcher") to watch over
portions of code that he is interested in. A "watcher" will be cc-ed to
changes that modify that portion of code, thereby giving him an opportunity
to make comments on codereview.chromium.org even before the change is
committed.
Refer: http://dev.chromium.org/developers/contributing-code/watchlists

When invoked directly from the base of a repository, this script lists out
the watchers for files given on the command line. This is useful to verify
changes to WATCHLISTS files.
"""

import logging
import os
import re
import sys


class Watchlists(object):
  """Manage Watchlists.

  This class provides mechanism to load watchlists for a repo and identify
  watchers.
  Usage:
    wl = Watchlists("/path/to/repo/root")
    watchers = wl.GetWatchersForPaths(["/path/to/file1",
                                       "/path/to/file2",])
  """

  _RULES = "WATCHLISTS"
  _RULES_FILENAME = _RULES
  _repo_root = None
  _defns = {}       # Definitions
  _watchlists = {}  # name to email mapping

  def __init__(self, repo_root):
    self._repo_root = repo_root
    self._LoadWatchlistRules()

  def _GetRulesFilePath(self):
    """Returns path to WATCHLISTS file."""
    return os.path.join(self._repo_root, self._RULES_FILENAME)

  def _HasWatchlistsFile(self):
    """Determine if watchlists are available for this repo."""
    return os.path.exists(self._GetRulesFilePath())

  def _ContentsOfWatchlistsFile(self):
    """Read the WATCHLISTS file and return its contents."""
    try:
      watchlists_file = open(self._GetRulesFilePath())
      contents = watchlists_file.read()
      watchlists_file.close()
      return contents
    except IOError, e:
      logging.error("Cannot read %s: %s" % (self._GetRulesFilePath(), e))
      return ''

  def _LoadWatchlistRules(self):
    """Load watchlists from WATCHLISTS file. Does nothing if not present."""
    if not self._HasWatchlistsFile():
      return

    contents = self._ContentsOfWatchlistsFile()
    watchlists_data = None
    try:
      watchlists_data = eval(contents, {'__builtins__': None}, None)
    except SyntaxError, e:
      logging.error("Cannot parse %s. %s" % (self._GetRulesFilePath(), e))
      return

    defns = watchlists_data.get("WATCHLIST_DEFINITIONS")
    if not defns:
      logging.error("WATCHLIST_DEFINITIONS not defined in %s" %
                    self._GetRulesFilePath())
      return
    watchlists = watchlists_data.get("WATCHLISTS")
    if not watchlists:
      logging.error("WATCHLISTS not defined in %s" % self._GetRulesFilePath())
      return
    self._defns = defns
    self._watchlists = watchlists

    # Verify that all watchlist names are defined
    for name in watchlists:
      if name not in defns:
        logging.error("%s not defined in %s" % (name, self._GetRulesFilePath()))

  def GetWatchersForPaths(self, paths):
    """Fetch the list of watchers for |paths|

    Args:
      paths: [path1, path2, ...]

    Returns:
      [u1@chromium.org, u2@gmail.com, ...]
    """
    watchers = set()  # A set, to avoid duplicates
    for path in paths:
      path = path.replace(os.sep, '/')
      for name, rule in self._defns.iteritems():
        if name not in self._watchlists:
          continue
        rex_str = rule.get('filepath')
        if not rex_str:
          continue
        if re.search(rex_str, path):
          map(watchers.add, self._watchlists[name])
    return list(watchers)


def main(argv):
  # Confirm that watchlists can be parsed and spew out the watchers
  if len(argv) < 2:
    print "Usage (from the base of repo):"
    print "  %s [file-1] [file-2] ...." % argv[0]
    return 1
  wl = Watchlists(os.getcwd())
  watchers = wl.GetWatchersForPaths(argv[1:])
  print watchers


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