# 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 style checking not specific to any one file type."""

import re
import sre_compile

# FIXME: Test this list in the same way that the list of CppChecker
#        categories is tested, for example by checking that all of its
#        elements appear in the unit tests. This should probably be done
#        after moving the relevant cpp_unittest.ErrorCollector code
#        into a shared location and refactoring appropriately.
categories = set([
    "whitespace/carriage_return",
    "whitespace/tab"])


# The regexp compilation caching is inlined in all regexp functions for
# performance reasons; factoring it out into a separate function turns out
# to be noticeably expensive.
_regexp_compile_cache = {}
_regexp_compile_cache_ignorecase = {}


def match(pattern, s):
    if not pattern in _regexp_compile_cache:
        _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
    return _regexp_compile_cache[pattern].match(s)


def search(pattern, string):
    if not pattern in _regexp_compile_cache:
        _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
    return _regexp_compile_cache[pattern].search(string)


def searchIgnorecase(pattern, string):
    if not pattern in _regexp_compile_cache_ignorecase:
        _regexp_compile_cache_ignorecase[pattern] = re.compile(pattern, flags=re.IGNORECASE)
    return _regexp_compile_cache_ignorecase[pattern].search(string)


def sub(pattern, replacement, s):
    if not pattern in _regexp_compile_cache:
        _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
    return _regexp_compile_cache[pattern].sub(replacement, s)


def subn(pattern, replacement, s):
    if not pattern in _regexp_compile_cache:
        _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
    return _regexp_compile_cache[pattern].subn(replacement, s)


class CarriageReturnChecker(object):

    """Supports checking for and handling carriage returns."""

    def __init__(self, handle_style_error):
        self._handle_style_error = handle_style_error

    def check(self, lines):
        """Check for and strip trailing carriage returns from lines."""
        for line_number in range(len(lines)):
            if not lines[line_number].endswith("\r"):
                continue

            self._handle_style_error(line_number + 1,  # Correct for offset.
                                     "whitespace/carriage_return",
                                     1,
                                     "One or more unexpected \\r (^M) found; "
                                     "better to use only a \\n")

            lines[line_number] = lines[line_number].rstrip("\r")

        return lines


class TabChecker(object):

    """Supports checking for and handling tabs."""

    def __init__(self, file_path, handle_style_error):
        self.file_path = file_path
        self.handle_style_error = handle_style_error

    def check(self, lines):
        # FIXME: share with cpp_style.
        for line_number, line in enumerate(lines):
            if "\t" in line:
                self.handle_style_error(line_number + 1,
                                        "whitespace/tab", 5,
                                        "Line contains tab character.")
