#!/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.
"""

from __future__ import print_function

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/tools
  tools_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
  src_dir = os.path.dirname(tools_dir)

  # Collect the args into the right buckets
  src_dirs = []
  grd_files = []
  for arg in sys.argv[1:]:
    if arg.lower().endswith('.grd') or arg.lower().endswith('.grdp'):
      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')
    ash_shortcut_viewer_dir = os.path.join(ash_base_dir, 'shortcut_viewer')
    chrome_dir = os.path.join(src_dir, 'chrome')
    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')
    services_dir = os.path.join(src_dir, 'services')
    ui_dir = os.path.join(src_dir, 'ui')
    ui_strings_dir = os.path.join(ui_dir, 'strings')
    ui_chromeos_dir = os.path.join(ui_dir, 'chromeos')
    grd_files = [
      os.path.join(ash_base_dir, 'ash_strings.grd'),
      os.path.join(ash_shortcut_viewer_dir, 'shortcut_viewer_strings.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(device_base_dir, 'fido', 'fido_strings.grd'),
      os.path.join(services_dir, 'services_strings.grd'),
      os.path.join(src_dir, 'chromeos', 'chromeos_strings.grd'),
      os.path.join(src_dir, 'extensions', 'strings', '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_strings_dir, 'app_locale_settings.grd'),
      os.path.join(ui_strings_dir, 'ui_strings.grd'),
      os.path.join(ui_chromeos_dir, 'ui_chromeos_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'),
      # 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())
