# Copyright (C) 2009 Google Inc. All rights reserved.
# Copyright (c) 2022 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#    * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#    * 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.
#    * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
# OWNER OR 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.

"""WebKit's Python module for interacting with patches."""

import logging
import re

from webkitcorepy import string_utils

_log = logging.getLogger(__name__)


# FIXME: This is broken. We should compile our regexps up-front
# instead of using a custom cache.
_regexp_compile_cache = {}


# FIXME: This function should be removed.
def match(pattern, string):
    """Matches the string with the pattern, caching the compiled regexp."""
    if not pattern in _regexp_compile_cache:
        _regexp_compile_cache[pattern] = re.compile(pattern)
    return _regexp_compile_cache[pattern].match(string)


# FIXME: This belongs on DiffParser (e.g. as to_svn_diff()).
def git_diff_to_svn_diff(line):
    """Converts a git formatted diff line to a svn formatted line.

    Args:
      line: A string representing a line of the diff.
    """
    # FIXME: This list should be a class member on DiffParser.
    # These regexp patterns should be compiled once instead of every time.
    conversion_patterns = ((r"^diff --git \w/(.+) \w/(?P<FilePath>.+)", lambda matched: "Index: " + matched.group('FilePath') + "\n"),
                           ("^new file.*", lambda matched: "\n"),
                           (r"^index (([0-9a-f]{7}\.\.[0-9a-f]{7})|([0-9a-f]{40}\.\.[0-9a-f]{40})) [0-9]{6}", lambda matched: "===================================================================\n"),
                           (r"^--- \w/(?P<FilePath>.+)", lambda matched: "--- " + matched.group('FilePath') + "\n"),
                           (r"^\+\+\+ \w/(?P<FilePath>.+)", lambda matched: "+++ " + matched.group('FilePath') + "\n"))

    for pattern, conversion in conversion_patterns:
        matched = match(pattern, line)
        if matched:
            return conversion(matched)
    return line


# This function exists so we can unittest get_diff_converter function
def svn_diff_to_svn_diff(line):
    return line


# FIXME: This method belongs on DiffParser
def get_diff_converter(lines):
    """Gets a converter function of diff lines.

    Args:
      lines: The lines of a diff file.
             If this line is git formatted, we'll return a
             converter from git to SVN.
    """
    for i, line in enumerate(lines[:-1]):
        line = string_utils.decode(line)

        # Stop when we find the first patch
        if line[:3] == "+++" and lines[i + 1] == "---":
            break
        if match(r"^diff --git \w/", line):
            return git_diff_to_svn_diff
    return svn_diff_to_svn_diff

_INITIAL_STATE = 1
_DECLARED_FILE_PATH = 2
_PROCESSING_CHUNK = 3


class DiffFile(object):
    """Contains the information for one file in a patch.

    The field "lines" is a list which contains tuples in this format:
       (deleted_line_number, new_line_number, line_string)
    If deleted_line_number is zero, it means this line is newly added.
    If new_line_number is zero, it means this line is deleted.
    """
    # FIXME: Tuples generally grow into classes.  We should consider
    # adding a DiffLine object.

    def added_or_modified_line_numbers(self):
        # This logic was moved from patchreader.py, but may not be
        # the right API for this object long-term.
        return [line[1] for line in self.lines if not line[0]]

    def __init__(self, filename):
        self.filename = filename
        self.lines = []

    def add_new_line(self, line_number, line):
        self.lines.append((0, line_number, line))

    def add_deleted_line(self, line_number, line):
        self.lines.append((line_number, 0, line))

    def add_unchanged_line(self, deleted_line_number, new_line_number, line):
        self.lines.append((deleted_line_number, new_line_number, line))


# If this is going to be called DiffParser, it should be a re-useable parser.
# Otherwise we should rename it to ParsedDiff or just Diff.
class DiffParser(object):
    """A parser for a patch file.

    The field "files" is a dict whose key is the filename and value is
    a DiffFile object.
    """

    VERSION_RE = re.compile(r'^\d+.\d+.\d+ \(\S+ Git-\d+\)$')

    def __init__(self, diff_input):
        """Parses a diff.

        Args:
          diff_input: An iterable object.
        """
        self.files = self._parse_into_diff_files(diff_input)

    # FIXME: This function is way too long and needs to be broken up.
    def _parse_into_diff_files(self, diff_input):
        files = {}
        state = _INITIAL_STATE
        current_file = None
        old_diff_line = None
        new_diff_line = None
        transform_line = get_diff_converter(diff_input)
        for line in diff_input:
            line = string_utils.decode(line).rstrip("\n")
            line = transform_line(line)

            file_declaration = match(r"^Index: (?P<FilePath>.+)", line)
            if file_declaration:
                filename = file_declaration.group('FilePath')
                current_file = DiffFile(filename)
                files[filename] = current_file
                state = _DECLARED_FILE_PATH
                continue

            lines_changed = match(r"^@@ -(?P<OldStartLine>\d+)(,\d+)? \+(?P<NewStartLine>\d+)(,\d+)? @@", line)
            if lines_changed:
                if state != _DECLARED_FILE_PATH and state != _PROCESSING_CHUNK:
                    _log.error('Unexpected line change without file path '
                               'declaration: %r' % line)
                old_diff_line = int(lines_changed.group('OldStartLine'))
                new_diff_line = int(lines_changed.group('NewStartLine'))
                state = _PROCESSING_CHUNK
                continue

            if state == _PROCESSING_CHUNK:
                if line.startswith('+'):
                    current_file.add_new_line(new_diff_line, line[1:])
                    new_diff_line += 1
                elif line.startswith('-'):
                    current_file.add_deleted_line(old_diff_line, line[1:])
                    old_diff_line += 1
                elif line.startswith(' '):
                    current_file.add_unchanged_line(old_diff_line, new_diff_line, line[1:])
                    old_diff_line += 1
                    new_diff_line += 1
                elif line == '\\ No newline at end of file' or not line or self.VERSION_RE.match(line):
                    # Nothing to do.  We may still have some added lines.
                    pass
                else:
                    _log.error('Unexpected diff format when parsing a '
                               'chunk: %r' % line)
        return files
