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

import codecs
import logging
import sys

from webkitpy.common.host import Host
from webkitpy.style import checker
from webkitpy.style.checker import StyleProcessor
from webkitpy.style.filereader import TextFileReader
from webkitpy.style.patchreader import PatchReader


_log = logging.getLogger(__name__)


def change_directory(filesystem, checkout_root, paths):
    """Change the working directory to the checkout root, if possible.

    If every path in the paths parameter is below the checkout root (or if
    the paths parameter is empty or None), this method changes the current
    working directory to the checkout root and converts the paths parameter
    as described below.

    This allows the paths being checked to be displayed relative to the
    checkout root, and for path-specific style checks to work as expected.
    Path-specific checks include whether files should be skipped, whether
    custom style rules should apply to certain files, etc.

    Args:
        paths: A list of paths to the files that should be checked for style.
            This argument can be None or the empty list if a git commit
            or all changes under the checkout root should be checked.
        checkout_root: The path to the root of the repository.

    Returns:
        A copy of the paths parameter -- possibly converted, as follows.
        If this method changed the current working directory to the
        checkout root, then the list is the paths parameter converted to
        normalized paths relative to the checkout root.
    """
    if paths is not None:
        paths = list(paths)

    if paths:
        # Then try converting all of the paths to paths relative to
        # the checkout root.
        rel_paths = []
        for path in paths:
            rel_path = filesystem.relpath(path, checkout_root)
            if rel_path.startswith(filesystem.pardir):
                # Then the path is not below the checkout root.  Since all
                # paths should be interpreted relative to the same root,
                # do not interpret any of the paths as relative to the
                # checkout root.  Interpret all of them relative to the
                # current working directory, and do not change the current
                # working directory.
                _log.warning(
                    """Path-dependent style checks may not work correctly:

  One of the given paths is outside the repository of the current
  working directory:

    Path: %s
    Checkout root: %s

  Pass only files below the checkout root to ensure correct results.
  See the help documentation for more info.
""",
                    path, checkout_root)

                return paths
            rel_paths.append(rel_path)
        # If we got here, the conversion was successful.
        paths = rel_paths

    _log.debug('Changing to checkout root: ' + checkout_root)
    filesystem.chdir(checkout_root)

    return paths


class CheckWebKitStyle(object):

    def _engage_awesome_stderr_hacks(self):
        # Change stderr to write with replacement characters so we don't die
        # if we try to print something containing non-ASCII characters.
        stderr = codecs.StreamReaderWriter(sys.stderr,
                                           codecs.getreader('utf8'),
                                           codecs.getwriter('utf8'),
                                           'replace')
        # Setting an "encoding" attribute on the stream is necessary to
        # prevent the logging module from raising an error.  See
        # the checker.configure_logging() function for more information.
        stderr.encoding = 'UTF-8'

        # FIXME: Change webkitpy.style so that we do not need to overwrite
        #        the global sys.stderr.  This involves updating the code to
        #        accept a stream parameter where necessary, and not calling
        #        sys.stderr explicitly anywhere.
        sys.stderr = stderr
        return stderr

    def main(self):
        args = sys.argv[1:]

        host = Host()

        stderr = self._engage_awesome_stderr_hacks()

        # Checking for the verbose flag before calling check_webkit_style_parser()
        # lets us enable verbose logging earlier.
        is_verbose = '-v' in args or '--verbose' in args

        checker.configure_logging(stream=stderr, is_verbose=is_verbose)
        _log.debug('Verbose logging enabled.')

        parser = checker.check_webkit_style_parser()
        (paths, options) = parser.parse(args)

        configuration = checker.check_webkit_style_configuration(options)

        paths = change_directory(host.filesystem, checkout_root=host.git().checkout_root, paths=paths)

        style_processor = StyleProcessor(configuration)
        file_reader = TextFileReader(host.filesystem, style_processor)

        if paths and not options.diff_files:
            file_reader.process_paths(paths)
        else:
            changed_files = paths if options.diff_files else None
            patch = host.git().create_patch(options.git_commit, changed_files=changed_files)
            patch_checker = PatchReader(file_reader)
            patch_checker.check(patch)

        error_count = style_processor.error_count
        file_count = file_reader.file_count
        delete_only_file_count = file_reader.delete_only_file_count

        _log.info('Total errors found: %d in %d files', error_count, file_count)
        # We fail when style errors are found or there are no checked files.
        return error_count > 0 or (file_count == 0 and delete_only_file_count == 0)
