# Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Supports the parsing of command-line options for check-webkit-style."""

import logging
from optparse import OptionParser
import os.path
import sys

from filter import validate_filter_rules
# This module should not import anything from checker.py.

_log = logging.getLogger(__name__)

_USAGE = """usage: %prog [--help] [options] [path1] [path2] ...

Overview:
  Check coding style according to WebKit style guidelines:

      http://webkit.org/coding/coding-style.html

  Path arguments can be files and directories.  If neither a git commit nor
  paths are passed, then all changes in your source control working directory
  are checked.

Style errors:
  This script assigns to every style error a confidence score from 1-5 and
  a category name.  A confidence score of 5 means the error is certainly
  a problem, and 1 means it could be fine.

  Category names appear in error messages in brackets, for example
  [whitespace/indent].  See the options section below for an option that
  displays all available categories and which are reported by default.

Filters:
  Use filters to configure what errors to report.  Filters are specified using
  a comma-separated list of boolean filter rules.  The script reports errors
  in a category if the category passes the filter, as described below.

  All categories start out passing.  Boolean filter rules are then evaluated
  from left to right, with later rules taking precedence.  For example, the
  rule "+foo" passes any category that starts with "foo", and "-foo" fails
  any such category.  The filter input "-whitespace,+whitespace/braces" fails
  the category "whitespace/tab" and passes "whitespace/braces".

  Examples: --filter=-whitespace,+whitespace/braces
            --filter=-whitespace,-runtime/printf,+runtime/printf_format
            --filter=-,+build/include_what_you_use

Paths:
  Certain style-checking behavior depends on the paths relative to
  the WebKit source root of the files being checked.  For example,
  certain types of errors may be handled differently for files in
  WebKit/gtk/webkit/ (e.g. by suppressing "readability/naming" errors
  for files in this directory).

  Consequently, if the path relative to the source root cannot be
  determined for a file being checked, then style checking may not
  work correctly for that file.  This can occur, for example, if no
  WebKit checkout can be found, or if the source root can be detected,
  but one of the files being checked lies outside the source tree.

  If a WebKit checkout can be detected and all files being checked
  are in the source tree, then all paths will automatically be
  converted to paths relative to the source root prior to checking.
  This is also useful for display purposes.

  Currently, this command can detect the source root only if the
  command is run from within a WebKit checkout (i.e. if the current
  working directory is below the root of a checkout).  In particular,
  it is not recommended to run this script from a directory outside
  a checkout.

  Running this script from a top-level WebKit source directory and
  checking only files in the source tree will ensure that all style
  checking behaves correctly -- whether or not a checkout can be
  detected.  This is because all file paths will already be relative
  to the source root and so will not need to be converted."""

_EPILOG = ("This script can miss errors and does not substitute for "
           "code review.")


# This class should not have knowledge of the flag key names.
class DefaultCommandOptionValues(object):

    """Stores the default check-webkit-style command-line options.

    Attributes:
      output_format: A string that is the default output format.
      min_confidence: An integer that is the default minimum confidence level.

    """

    def __init__(self, min_confidence, output_format):
        self.min_confidence = min_confidence
        self.output_format = output_format


# This class should not have knowledge of the flag key names.
class CommandOptionValues(object):

    """Stores the option values passed by the user via the command line.

    Attributes:
      is_verbose: A boolean value of whether verbose logging is enabled.

      filter_rules: The list of filter rules provided by the user.
                    These rules are appended to the base rules and
                    path-specific rules and so take precedence over
                    the base filter rules, etc.

      git_commit: A string representing the git commit to check.
                  The default is None.

      min_confidence: An integer between 1 and 5 inclusive that is the
                      minimum confidence level of style errors to report.
                      The default is 1, which reports all errors.

      output_format: A string that is the output format.  The supported
                     output formats are "emacs" which emacs can parse
                     and "vs7" which Microsoft Visual Studio 7 can parse.

    """
    def __init__(self,
                 filter_rules=None,
                 git_commit=None,
                 diff_files=None,
                 is_verbose=False,
                 min_confidence=1,
                 output_format="emacs"):
        if filter_rules is None:
            filter_rules = []

        if (min_confidence < 1) or (min_confidence > 5):
            raise ValueError('Invalid "min_confidence" parameter: value '
                             "must be an integer between 1 and 5 inclusive. "
                             'Value given: "%s".' % min_confidence)

        if output_format not in ("emacs", "vs7"):
            raise ValueError('Invalid "output_format" parameter: '
                             'value must be "emacs" or "vs7". '
                             'Value given: "%s".' % output_format)

        self.filter_rules = filter_rules
        self.git_commit = git_commit
        self.diff_files = diff_files
        self.is_verbose = is_verbose
        self.min_confidence = min_confidence
        self.output_format = output_format

    # Useful for unit testing.
    def __eq__(self, other):
        """Return whether this instance is equal to another."""
        if self.filter_rules != other.filter_rules:
            return False
        if self.git_commit != other.git_commit:
            return False
        if self.diff_files != other.diff_files:
            return False
        if self.is_verbose != other.is_verbose:
            return False
        if self.min_confidence != other.min_confidence:
            return False
        if self.output_format != other.output_format:
            return False

        return True

    # Useful for unit testing.
    def __ne__(self, other):
        # Python does not automatically deduce this from __eq__().
        return not self.__eq__(other)


class ArgumentPrinter(object):

    """Supports the printing of check-webkit-style command arguments."""

    def _flag_pair_to_string(self, flag_key, flag_value):
        return '--%(key)s=%(val)s' % {'key': flag_key, 'val': flag_value }

    def to_flag_string(self, options):
        """Return a flag string of the given CommandOptionValues instance.

        This method orders the flag values alphabetically by the flag key.

        Args:
          options: A CommandOptionValues instance.

        """
        flags = {}
        flags['min-confidence'] = options.min_confidence
        flags['output'] = options.output_format
        # Only include the filter flag if user-provided rules are present.
        filter_rules = options.filter_rules
        if filter_rules:
            flags['filter'] = ",".join(filter_rules)
        if options.git_commit:
            flags['git-commit'] = options.git_commit
        if options.diff_files:
            flags['diff_files'] = options.diff_files

        flag_string = ''
        # Alphabetizing lets us unit test this method.
        for key in sorted(flags.keys()):
            flag_string += self._flag_pair_to_string(key, flags[key]) + ' '

        return flag_string.strip()


class ArgumentParser(object):

    # FIXME: Move the documentation of the attributes to the __init__
    #        docstring after making the attributes internal.
    """Supports the parsing of check-webkit-style command arguments.

    Attributes:
      create_usage: A function that accepts a DefaultCommandOptionValues
                    instance and returns a string of usage instructions.
                    Defaults to the function that generates the usage
                    string for check-webkit-style.
      default_options: A DefaultCommandOptionValues instance that provides
                       the default values for options not explicitly
                       provided by the user.
      stderr_write: A function that takes a string as a parameter and
                    serves as stderr.write.  Defaults to sys.stderr.write.
                    This parameter should be specified only for unit tests.

    """

    def __init__(self,
                 all_categories,
                 default_options,
                 base_filter_rules=None,
                 mock_stderr=None,
                 usage=None):
        """Create an ArgumentParser instance.

        Args:
          all_categories: The set of all available style categories.
          default_options: See the corresponding attribute in the class
                           docstring.
        Keyword Args:
          base_filter_rules: The list of filter rules at the beginning of
                             the list of rules used to check style.  This
                             list has the least precedence when checking
                             style and precedes any user-provided rules.
                             The class uses this parameter only for display
                             purposes to the user.  Defaults to the empty list.
          create_usage: See the documentation of the corresponding
                        attribute in the class docstring.
          stderr_write: See the documentation of the corresponding
                        attribute in the class docstring.

        """
        if base_filter_rules is None:
            base_filter_rules = []
        stderr = sys.stderr if mock_stderr is None else mock_stderr
        if usage is None:
            usage = _USAGE

        self._all_categories = all_categories
        self._base_filter_rules = base_filter_rules

        # FIXME: Rename these to reflect that they are internal.
        self.default_options = default_options
        self.stderr_write = stderr.write

        self._parser = self._create_option_parser(stderr=stderr,
            usage=usage,
            default_min_confidence=self.default_options.min_confidence,
            default_output_format=self.default_options.output_format)

    def _create_option_parser(self, stderr, usage,
                              default_min_confidence, default_output_format):
        # Since the epilog string is short, it is not necessary to replace
        # the epilog string with a mock epilog string when testing.
        # For this reason, we use _EPILOG directly rather than passing it
        # as an argument like we do for the usage string.
        parser = OptionParser(usage=usage, epilog=_EPILOG)

        filter_help = ('set a filter to control what categories of style '
                       'errors to report.  Specify a filter using a comma-'
                       'delimited list of boolean filter rules, for example '
                       '"--filter -whitespace,+whitespace/braces".  To display '
                       'all categories and which are enabled by default, pass '
                       """no value (e.g. '-f ""' or '--filter=').""")
        parser.add_option("-f", "--filter-rules", metavar="RULES",
                          dest="filter_value", help=filter_help)

        git_commit_help = ("check all changes in the given commit. "
                           "Use 'commit_id..' to check all changes after commmit_id")
        parser.add_option("-g", "--git-diff", "--git-commit",
                          metavar="COMMIT", dest="git_commit", help=git_commit_help,)

        diff_files_help = "diff the files passed on the command line rather than checking the style of every line"
        parser.add_option("--diff-files", action="store_true", dest="diff_files", default=False, help=diff_files_help)

        min_confidence_help = ("set the minimum confidence of style errors "
                               "to report.  Can be an integer 1-5, with 1 "
                               "displaying all errors.  Defaults to %default.")
        parser.add_option("-m", "--min-confidence", metavar="INT",
                          type="int", dest="min_confidence",
                          default=default_min_confidence,
                          help=min_confidence_help)

        output_format_help = ('set the output format, which can be "emacs" '
                              'or "vs7" (for Visual Studio).  '
                              'Defaults to "%default".')
        parser.add_option("-o", "--output-format", metavar="FORMAT",
                          choices=["emacs", "vs7"],
                          dest="output_format", default=default_output_format,
                          help=output_format_help)

        verbose_help = "enable verbose logging."
        parser.add_option("-v", "--verbose", dest="is_verbose", default=False,
                          action="store_true", help=verbose_help)

        # Override OptionParser's error() method so that option help will
        # also display when an error occurs.  Normally, just the usage
        # string displays and not option help.
        parser.error = self._parse_error

        # Override OptionParser's print_help() method so that help output
        # does not render to the screen while running unit tests.
        print_help = parser.print_help
        parser.print_help = lambda: print_help(file=stderr)

        return parser

    def _parse_error(self, error_message):
        """Print the help string and an error message, and exit."""
        # The method format_help() includes both the usage string and
        # the flag options.
        help = self._parser.format_help()
        # Separate help from the error message with a single blank line.
        self.stderr_write(help + "\n")
        if error_message:
            _log.error(error_message)

        # Since we are using this method to replace/override the Python
        # module optparse's OptionParser.error() method, we match its
        # behavior and exit with status code 2.
        #
        # As additional background, Python documentation says--
        #
        # "Unix programs generally use 2 for command line syntax errors
        #  and 1 for all other kind of errors."
        #
        # (from http://docs.python.org/library/sys.html#sys.exit )
        sys.exit(2)

    def _exit_with_categories(self):
        """Exit and print the style categories and default filter rules."""
        self.stderr_write('\nAll categories:\n')
        for category in sorted(self._all_categories):
            self.stderr_write('    ' + category + '\n')

        self.stderr_write('\nDefault filter rules**:\n')
        for filter_rule in sorted(self._base_filter_rules):
            self.stderr_write('    ' + filter_rule + '\n')
        self.stderr_write('\n**The command always evaluates the above rules, '
                          'and before any --filter flag.\n\n')

        sys.exit(0)

    def _parse_filter_flag(self, flag_value):
        """Parse the --filter flag, and return a list of filter rules.

        Args:
          flag_value: A string of comma-separated filter rules, for
                      example "-whitespace,+whitespace/indent".

        """
        filters = []
        for uncleaned_filter in flag_value.split(','):
            filter = uncleaned_filter.strip()
            if not filter:
                continue
            filters.append(filter)
        return filters

    def parse(self, args):
        """Parse the command line arguments to check-webkit-style.

        Args:
          args: A list of command-line arguments as returned by sys.argv[1:].

        Returns:
          A tuple of (paths, options)

          paths: The list of paths to check.
          options: A CommandOptionValues instance.

        """
        (options, paths) = self._parser.parse_args(args=args)

        filter_value = options.filter_value
        git_commit = options.git_commit
        diff_files = options.diff_files
        is_verbose = options.is_verbose
        min_confidence = options.min_confidence
        output_format = options.output_format

        if filter_value is not None and not filter_value:
            # Then the user explicitly passed no filter, for
            # example "-f ''" or "--filter=".
            self._exit_with_categories()

        # Validate user-provided values.

        min_confidence = int(min_confidence)
        if (min_confidence < 1) or (min_confidence > 5):
            self._parse_error('option --min-confidence: invalid integer: '
                              '%s: value must be between 1 and 5'
                              % min_confidence)

        if filter_value:
            filter_rules = self._parse_filter_flag(filter_value)
        else:
            filter_rules = []

        try:
            validate_filter_rules(filter_rules, self._all_categories)
        except ValueError, err:
            self._parse_error(err)

        options = CommandOptionValues(filter_rules=filter_rules,
                                      git_commit=git_commit,
                                      diff_files=diff_files,
                                      is_verbose=is_verbose,
                                      min_confidence=min_confidence,
                                      output_format=output_format)

        return (paths, options)

