# Copyright 2014 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 for Chromium HTML resources. See chrome/browser/PRESUBMIT.py.
"""

import regex_check


class HtmlChecker(object):
  def __init__(self, input_api, output_api, file_filter=None):
    self.input_api = input_api
    self.output_api = output_api
    self.file_filter = file_filter

  def ClassesUseDashFormCheck(self, line_number, line):
    msg = "Classes should use dash-form."
    re = self.input_api.re
    class_regex = re.compile("""
        (?:^|\s)                    # start of line or whitespace
        (class="[^"]*[A-Z_][^"]*")  # class contains caps or '_'
        """,
        re.VERBOSE)

    # $i18n{...} messes with highlighting. Special path for this.
    if "$i18n{" in line:
      match = re.search(class_regex, re.sub("\$i18n{[^}]+}", "", line))
      return "  line %d: %s" % (line_number, msg) if match else ""

    return regex_check.RegexCheck(re, line_number, line, class_regex, msg)

  def DoNotCloseSingleTagsCheck(self, line_number, line):
    regex = r"(/>)"
    return regex_check.RegexCheck(self.input_api.re, line_number, line, regex,
        "Do not close single tags.")

  def DoNotUseBrElementCheck(self, line_number, line):
    regex = r"(<br)"
    return regex_check.RegexCheck(self.input_api.re, line_number, line, regex,
        "Do not use <br>; place blocking elements (<div>) as appropriate.")

  def DoNotUseInputTypeButtonCheck(self, line_number, line):
    regex = self.input_api.re.compile("""
        (<input [^>]*  # "<input " followed by anything but ">"
        type="button"  # type="button"
        [^>]*>)        # anything but ">" then ">"
        """,
        self.input_api.re.VERBOSE)
    return regex_check.RegexCheck(self.input_api.re, line_number, line, regex,
        'Use the button element instead of <input type="button">')

  def DoNotUseSingleQuotesCheck(self, line_number, line):
    regex = self.input_api.re.compile("""
        <\S+                           # The tag name.
        (?:\s+\S+\$?="[^"]*"|\s+\S+)*  # Correctly quoted or non-value props.
        \s+(\S+\$?='[^']*')            # Find incorrectly quoted (foo='bar').
        [^>]*>                         # To the end of the tag.
        """,
        self.input_api.re.MULTILINE | self.input_api.re.VERBOSE)
    return regex_check.RegexCheck(self.input_api.re, line_number, line, regex,
        'Use double quotes rather than single quotes in HTML properties')

  def I18nContentJavaScriptCaseCheck(self, line_number, line):
    regex = self.input_api.re.compile("""
        (?:^|\s)                      # start of line or whitespace
        i18n-content="                # i18n-content="
        ([A-Z][^"]*|[^"]*[-_][^"]*)"  # starts with caps or contains '-' or '_'
        """,
        self.input_api.re.VERBOSE)
    return regex_check.RegexCheck(self.input_api.re, line_number, line, regex,
        "For i18n-content use javaScriptCase.")

  def LabelCheck(self, line_number, line):
    regex = self.input_api.re.compile("""
        (?:^|\s)     # start of line or whitespace
        <label[^>]+? # <label tag
        (for=)       # for=
        """,
        self.input_api.re.VERBOSE)
    return regex_check.RegexCheck(self.input_api.re, line_number, line, regex,
        "Avoid 'for' attribute on <label>. Place the input within the <label>, "
        "or use aria-labelledby for <select>.")

  def QuotePolymerBindings(self, line_number, line):
    regex = self.input_api.re.compile(r"=(\[\[|\{\{)")
    return regex_check.RegexCheck(self.input_api.re, line_number, line, regex,
        'Please use quotes around Polymer bindings (i.e. attr="[[prop]]")')

  def RunChecks(self):
    """Check for violations of the Chromium web development style guide. See
       https://chromium.googlesource.com/chromium/src/+/master/styleguide/web/web.md
    """
    results = []

    affected_files = self.input_api.AffectedFiles(file_filter=self.file_filter,
                                                  include_deletes=False)

    for f in affected_files:
      if not f.LocalPath().endswith('.html'):
        continue

      errors = []

      for line_number, line in f.ChangedContents():
        errors.extend(filter(None, [
            self.ClassesUseDashFormCheck(line_number, line),
            self.DoNotCloseSingleTagsCheck(line_number, line),
            self.DoNotUseBrElementCheck(line_number, line),
            self.DoNotUseInputTypeButtonCheck(line_number, line),
            self.I18nContentJavaScriptCaseCheck(line_number, line),
            self.LabelCheck(line_number, line),
            self.QuotePolymerBindings(line_number, line),
        ]))

      if errors:
        abs_local_path = f.AbsoluteLocalPath()
        file_indicator = 'Found HTML style issues in %s' % abs_local_path
        prompt_msg = file_indicator + '\n\n' + '\n'.join(errors) + '\n'
        results.append(self.output_api.PresubmitPromptWarning(prompt_msg))

    return results
