#!/usr/bin/env 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.

"""Without any args, this simply loads the IDs out of a bunch of the Chrome GRD
files, and then checks the subset of the code that loads the strings to try
and figure out what isn't in use any more.
You can give paths to GRD files and source directories to control what is
check instead.
"""

import os
import re
import sys
import xml.sax

# Extra messages along the way
# 1 - Print ids that are found in sources but not in the found id set
# 2 - Files that aren't processes (don't match the source name regex)
DEBUG = 0


class GrdIDExtractor(xml.sax.handler.ContentHandler):
  """Extracts the IDs from messages in GRIT files"""
  def __init__(self):
    self.id_set_ = set()

  def startElement(self, name, attrs):
    if name == 'message':
      self.id_set_.add(attrs['name'])

  def allIDs(self):
    """Return all the IDs found"""
    return self.id_set_.copy()


def CheckForUnusedGrdIDsInSources(grd_files, src_dirs):
  """Will collect the message ids out of the given GRD files and then scan
  the source directories to try and figure out what ids are not currently
  being used by any source.

  grd_files:
    A list of GRD files to collect the ids from.
  src_dirs:
    A list of directories to walk looking for source files.
  """
  # Collect all the ids into a large map
  all_ids = set()
  file_id_map = {}
  for y in grd_files:
    handler = GrdIDExtractor()
    xml.sax.parse(y, handler)
    files_ids = handler.allIDs()
    file_id_map[y] = files_ids
    all_ids |= files_ids


  # The regex that will be used to check sources
  id_regex = re.compile('IDS_[A-Z0-9_]+')

  # Make sure the regex matches every id found.
  got_err = False
  for x in all_ids:
    match = id_regex.search(x)
    if match is None:
      print 'ERROR: "%s" did not match our regex' % (x)
      got_err = True
    if not match.group(0) is x:
      print 'ERROR: "%s" did not fully match our regex' % (x)
      got_err = True
  if got_err:
    return 1

  # The regex for deciding what is a source file
  src_regex = re.compile('\.(([chm])|(mm)|(cc)|(cp)|(cpp)|(xib)|(py))$')

  ids_left = all_ids.copy()

  # Scanning time.
  for src_dir in src_dirs:
    for root, dirs, files in os.walk(src_dir):
      # Remove svn directories from recursion
      if '.svn' in dirs:
        dirs.remove('.svn')
      for file in files:
        if src_regex.search(file.lower()):
          full_path = os.path.join(root, file)
          src_file_contents = open(full_path).read()
          for match in sorted(set(id_regex.findall(src_file_contents))):
            if match in ids_left:
              ids_left.remove(match)
            if DEBUG:
              if not match in all_ids:
                print '%s had "%s", which was not in the found IDs' % \
                  (full_path, match)
        elif DEBUG > 1:
          full_path = os.path.join(root, file)
          print 'Skipping %s.' % (full_path)

  # Anything left?
  if len(ids_left) > 0:
    print 'The following ids are in GRD files, but *appear* to be unused:'
    for file_path, file_ids in file_id_map.iteritems():
      missing = ids_left.intersection(file_ids)
      if len(missing) > 0:
        print '  %s:' % (file_path)
        print '\n'.join('    %s' % (x) for x in sorted(missing))

  return 0


def main():
  # script lives in src/chrome/tools
  chrome_tools_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
  src_dir = os.path.dirname(os.path.dirname(chrome_tools_dir))
  chrome_dir = os.path.join(src_dir, 'chrome')

  # Collect the args into the right buckets
  src_dirs = []
  grd_files = []
  for arg in sys.argv[1:]:
    if arg.lower().endswith('.grd'):
      grd_files.append(arg)
    else:
      src_dirs.append(arg)

  # If no GRD files were given, default them:
  if len(grd_files) == 0:
    ash_base_dir = os.path.join(src_dir, 'ash')
    chrome_app_dir = os.path.join(chrome_dir, 'app')
    chrome_app_res_dir = os.path.join(chrome_app_dir, 'resources')
    device_base_dir = os.path.join(src_dir, 'device')
    ui_base_dir = os.path.join(src_dir, 'ui', 'base',)
    ui_base_strings_dir = os.path.join(ui_base_dir, 'strings')
    grd_files = [
      os.path.join(ash_base_dir, 'ash_strings.grd'),
      os.path.join(ash_base_dir, 'resources', 'ash_resources.grd'),
      os.path.join(chrome_app_dir, 'chromium_strings.grd'),
      os.path.join(chrome_app_dir, 'generated_resources.grd'),
      os.path.join(chrome_app_dir, 'google_chrome_strings.grd'),
      os.path.join(chrome_app_res_dir, 'locale_settings.grd'),
      os.path.join(chrome_app_res_dir, 'locale_settings_chromiumos.grd'),
      os.path.join(chrome_app_res_dir, 'locale_settings_google_chromeos.grd'),
      os.path.join(chrome_app_res_dir, 'locale_settings_linux.grd'),
      os.path.join(chrome_app_res_dir, 'locale_settings_mac.grd'),
      os.path.join(chrome_app_res_dir, 'locale_settings_win.grd'),
      os.path.join(chrome_app_dir, 'theme', 'theme_resources.grd'),
      os.path.join(chrome_dir, 'browser', 'browser_resources.grd'),
      os.path.join(chrome_dir, 'common', 'common_resources.grd'),
      os.path.join(chrome_dir, 'renderer', 'resources',
                   'renderer_resources.grd'),
      os.path.join(device_base_dir, 'bluetooth', 'bluetooth_strings.grd'),
      os.path.join(src_dir, 'extensions', 'extensions_strings.grd'),
      os.path.join(src_dir, 'ui', 'resources', 'ui_resources.grd'),
      os.path.join(src_dir, 'ui', 'webui', 'resources', 'webui_resources.grd'),
      os.path.join(ui_base_strings_dir, 'app_locale_settings.grd'),
      os.path.join(ui_base_strings_dir, 'ui_strings.grd'),
    ]

  # If no source directories were given, default them:
  if len(src_dirs) == 0:
    src_dirs = [
      os.path.join(src_dir, 'app'),
      os.path.join(src_dir, 'ash'),
      os.path.join(src_dir, 'chrome'),
      os.path.join(src_dir, 'components'),
      os.path.join(src_dir, 'content'),
      os.path.join(src_dir, 'device'),
      os.path.join(src_dir, 'extensions'),
      os.path.join(src_dir, 'ui'),
      os.path.join(src_dir, 'views'),
      # nsNSSCertHelper.cpp has a bunch of ids
      os.path.join(src_dir, 'third_party', 'mozilla_security_manager'),
      os.path.join(chrome_dir, 'installer'),
    ]

  return CheckForUnusedGrdIDsInSources(grd_files, src_dirs)


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