# 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.

"""Presubmit script for changes affecting extensions.

See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into gcl.
"""
import fnmatch
import os
import re

EXTENSIONS_PATH = os.path.join('chrome', 'common', 'extensions')
DOCS_PATH = os.path.join(EXTENSIONS_PATH, 'docs')
SERVER2_PATH = os.path.join(DOCS_PATH, 'server2')
API_PATH = os.path.join(EXTENSIONS_PATH, 'api')
TEMPLATES_PATH = os.path.join(DOCS_PATH, 'templates')
PRIVATE_TEMPLATES_PATH = os.path.join(TEMPLATES_PATH, 'private')
PUBLIC_TEMPLATES_PATH = os.path.join(TEMPLATES_PATH, 'public')
INTROS_PATH = os.path.join(TEMPLATES_PATH, 'intros')
ARTICLES_PATH = os.path.join(TEMPLATES_PATH, 'articles')

LOCAL_PUBLIC_TEMPLATES_PATH = os.path.join('docs',
                                           'templates',
                                           'public')

def _ReadFile(filename):
  with open(filename) as f:
    return f.read()

def _ListFilesInPublic():
  all_files = []
  for path, dirs, files in os.walk(LOCAL_PUBLIC_TEMPLATES_PATH):
    all_files.extend(
        os.path.join(path, filename)[len(LOCAL_PUBLIC_TEMPLATES_PATH + os.sep):]
        for filename in files)
  return all_files

def _UnixName(name):
  name = os.path.splitext(name)[0]
  s1 = re.sub('([a-z])([A-Z])', r'\1_\2', name)
  s2 = re.sub('([A-Z]+)([A-Z][a-z])', r'\1_\2', s1)
  return s2.replace('.', '_').lower()

def _FindMatchingTemplates(template_name, template_path_list):
  matches = []
  unix_name = _UnixName(template_name)
  for template in template_path_list:
    if unix_name == _UnixName(template.split(os.sep)[-1]):
      matches.append(template)
  return matches

def _SanitizeAPIName(name, api_path):
  if not api_path.endswith(os.sep):
    api_path += os.sep
  filename = os.path.splitext(name)[0][len(api_path):].replace(os.sep, '_')
  if 'experimental' in filename:
    filename = 'experimental_' + filename.replace('experimental_', '')
  return filename

def _CreateIntegrationTestArgs(affected_files):
  if (any(fnmatch.fnmatch(name, '%s*.py' % SERVER2_PATH)
         for name in affected_files) or
      any(fnmatch.fnmatch(name, '%s*' % PRIVATE_TEMPLATES_PATH)
          for name in affected_files)):
    return ['-a']
  args = []
  for name in affected_files:
    if (fnmatch.fnmatch(name, '%s*' % PUBLIC_TEMPLATES_PATH) or
        fnmatch.fnmatch(name, '%s*' % INTROS_PATH) or
        fnmatch.fnmatch(name, '%s*' % ARTICLES_PATH)):
      args.extend(_FindMatchingTemplates(name.split(os.sep)[-1],
                                         _ListFilesInPublic()))
    if fnmatch.fnmatch(name, '%s*' % API_PATH):
      args.extend(_FindMatchingTemplates(_SanitizeAPIName(name, API_PATH),
                                         _ListFilesInPublic()))
  return args

def _CheckHeadingIDs(input_api):
  ids_re = re.compile('<h[23].*id=.*?>')
  headings_re = re.compile('<h[23].*?>')
  bad_files = []
  for name in input_api.AbsoluteLocalPaths():
    if not os.path.exists(name):
      continue
    if (fnmatch.fnmatch(name, '*%s*' % INTROS_PATH) or
        fnmatch.fnmatch(name, '*%s*' % ARTICLES_PATH)):
      contents = input_api.ReadFile(name)
      if (len(re.findall(headings_re, contents)) !=
          len(re.findall(ids_re, contents))):
        bad_files.append(name)
  return bad_files

def _CheckLinks(input_api, output_api, results):
  for affected_file in input_api.AffectedFiles():
    name = affected_file.LocalPath()
    absolute_path = affected_file.AbsoluteLocalPath()
    if not os.path.exists(absolute_path):
      continue
    if (fnmatch.fnmatch(name, '%s*' % PUBLIC_TEMPLATES_PATH) or
        fnmatch.fnmatch(name, '%s*' % INTROS_PATH) or
        fnmatch.fnmatch(name, '%s*' % ARTICLES_PATH) or
        fnmatch.fnmatch(name, '%s*' % API_PATH)):
      contents = _ReadFile(absolute_path)
      args = []
      if input_api.platform == 'win32':
        args = [input_api.python_executable]
      args.extend([os.path.join('docs', 'server2', 'link_converter.py'),
                   '-o',
                   '-f',
                   absolute_path])
      output = input_api.subprocess.check_output(
          args,
          cwd=input_api.PresubmitLocalPath(),
          universal_newlines=True)
      if output != contents:
        changes = ''
        for i, (line1, line2) in enumerate(
            zip(contents.split('\n'), output.split('\n'))):
          if line1 != line2:
            changes = ('%s\nLine %d:\n-%s\n+%s\n' %
                (changes, i + 1, line1, line2))
        if changes:
          results.append(output_api.PresubmitPromptWarning(
              'File %s may have an old-style <a> link to an API page. Please '
              'run docs/server2/link_converter.py to convert the link[s], or '
              'convert them manually.\n\nSuggested changes are: %s' %
              (name, changes)))

def _CheckChange(input_api, output_api):
  results = [
      output_api.PresubmitError('File %s needs an id for each heading.' % name)
      for name in _CheckHeadingIDs(input_api)]
  try:
    integration_test = []
    # From depot_tools/presubmit_canned_checks.py:529
    if input_api.platform == 'win32':
      integration_test = [input_api.python_executable]
    integration_test.append(
        os.path.join('docs', 'server2', 'integration_test.py'))
    integration_test.extend(_CreateIntegrationTestArgs(input_api.LocalPaths()))
    input_api.subprocess.check_call(integration_test,
                                    cwd=input_api.PresubmitLocalPath())
  except input_api.subprocess.CalledProcessError:
    results.append(output_api.PresubmitError('IntegrationTest failed!'))
  _CheckLinks(input_api, output_api, results)
  return results

def CheckChangeOnUpload(input_api, output_api):
  return _CheckChange(input_api, output_api)

def CheckChangeOnCommit(input_api, output_api):
  return _CheckChange(input_api, output_api)
