# Copyright (C) 2009, Google 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 parsing and modifying ChangeLog files

import logging
import re
import textwrap

from webkitcorepy import StringIO, unicode

from webkitpy.common.config.committers import CommitterList
from webkitpy.common.system.filesystem import FileSystem
import webkitpy.common.config.urls as config_urls

_log = logging.getLogger(__name__)


# FIXME: parse_bug_id_from_changelog should not be a free function.
# Parse the bug ID out of a Changelog message based on the format that is
# used by prepare-ChangeLog
def parse_bug_id_from_changelog(message):
    if not message:
        return None
    match = re.search(r"^\s*" + config_urls.bug_url_short + "$", message, re.MULTILINE)
    if match:
        return int(match.group('bug_id'))
    match = re.search(r"^\s*" + config_urls.bug_url_long + "$", message, re.MULTILINE)
    if match:
        return int(match.group('bug_id'))
    # We weren't able to find a bug URL in the format used by prepare-ChangeLog. Fall back to the
    # first bug URL found anywhere in the message.
    return config_urls.parse_bug_id(message)


class ChangeLogEntry(object):
    # e.g. 2009-06-03  Eric Seidel  <eric@webkit.org>
    date_line_regexp = r'^(?P<date>\d{4}-\d{2}-\d{2})\s+(?P<authors>(?P<name>[^<]+?)\s+<(?P<email>[^<>]+)>.*?)$'

    # e.g. * Source/WebCore/page/EventHandler.cpp: Implement FooBarQuux.
    touched_files_regexp = r'^\s*\*\s*(?P<file>[A-Za-z0-9_\-\./\\]+)\s*\:'
    # e.g. (ChangeLogEntry.touched_functions): Added.
    touched_functions_regexp = r'^\s*\((?P<function>[^)]*)\):'

    radar_id_regexp = r'^\s*(<?rdar://(problems?/)?)?(?P<radar_id>-?\d{7,})>?'

    # e.g. Reviewed by Darin Adler.
    # (Discard everything after the first period to match more invalid lines.)
    reviewed_by_regexp = r'^\s*((\w+\s+)+and\s+)?(Review|Rubber(\s*|-)stamp)(s|ed)?\s+([a-z]+\s+)*?by\s+(?P<reviewer>.*?)[\.,]?\s*$'

    reviewed_byless_regexp = r'^\s*((Review|Rubber(\s*|-)stamp)(s|ed)?|RS)(\s+|\s*=\s*)(?P<reviewer>([A-Z]\w+\s*)+)[\.,]?\s*$'

    reviewer_name_noise_regexp = re.compile(r"""
    (\s+((tweaked\s+)?and\s+)?(landed|committed|okayed)\s+by.+) # "landed by", "commented by", etc...
    |(^(Reviewed\s+)?by\s+) # extra "Reviewed by" or "by"
    |([(<]\s*[\w_\-\.]+@[\w_\-\.]+[>)]) # email addresses
    |([(<](https?://?bugs.)webkit.org[^>)]+[>)]) # bug url
    |("[^"]+") # wresler names like 'Sean/Shawn/Shaun' in 'Geoffrey "Sean/Shawn/Shaun" Garen'
    |('[^']+') # wresler names like "The Belly" in "Sam 'The Belly' Weinig"
    |((Mr|Ms|Dr|Mrs|Prof)\.(\s+|$))
    """, re.IGNORECASE | re.VERBOSE)

    reviewer_name_casesensitive_noise_regexp = re.compile(r"""
    ((\s+|^)(and\s+)?([a-z-]+\s+){5,}by\s+) # e.g. "and given a good once-over by"
    |(\(\s*(?!(and|[A-Z])).+\)) # any parenthesis that doesn't start with "and" or a capital letter
    |(with(\s+[a-z-]+)+) # phrases with "with no hesitation" in "Sam Weinig with no hesitation"
    """, re.VERBOSE)

    reviewer_name_noise_needing_a_backreference_regexp = re.compile(r"""
    (\S\S)\.(?:(\s.+|$)) # Text after the two word characters (don't match initials) and a period followed by a space.
    """, re.IGNORECASE | re.VERBOSE)

    nobody_regexp = re.compile(r"""(\s+|^)nobody(
    ((,|\s+-)?\s+(\w+\s+)+fix.*) # e.g. nobody, build fix...
    |(\s*\([^)]+\).*) # NOBODY (..)...
    |$)""", re.IGNORECASE | re.VERBOSE)

    # e.g. == Rolled over to ChangeLog-2011-02-16 ==
    rolled_over_regexp = r'^== Rolled over to ChangeLog-\d{4}-\d{2}-\d{2} ==$'

    split_names_regexp = r'\s*(?:,(?:\s+and\s+|&)?|(?:^|\s+)and\s+|&&|[/+&])\s*'

    def __init__(self, contents, committer_list=None, revision=None):
        self._contents = contents
        self._committer_list = committer_list or CommitterList()
        self._revision = revision
        self._parse_entry()

    @classmethod
    def _parse_radar_id(cls, text):
        if not text:
            return None
        match = re.search(ChangeLogEntry.radar_id_regexp, text, re.MULTILINE | re.IGNORECASE)
        if not match:
            return None
        radar_id = int(match.group('radar_id'))
        if radar_id < 0:
            return None

        return radar_id

    @classmethod
    def _parse_reviewer_text(cls, text):
        match = re.search(ChangeLogEntry.reviewed_by_regexp, text, re.MULTILINE | re.IGNORECASE)
        if not match:
            # There are cases where people omit "by". We match it only if reviewer part looked nice
            # in order to avoid matching random lines that start with Reviewed
            match = re.search(ChangeLogEntry.reviewed_byless_regexp, text, re.MULTILINE | re.IGNORECASE)
        if not match:
            return None, None

        reviewer_text = match.group("reviewer")

        reviewer_text = ChangeLogEntry.nobody_regexp.sub('', reviewer_text)
        reviewer_text = ChangeLogEntry.reviewer_name_noise_regexp.sub('', reviewer_text)
        reviewer_text = ChangeLogEntry.reviewer_name_casesensitive_noise_regexp.sub('', reviewer_text)
        reviewer_text = ChangeLogEntry.reviewer_name_noise_needing_a_backreference_regexp.sub(r'\1', reviewer_text)
        reviewer_text = reviewer_text.replace('(', '').replace(')', '')
        reviewer_text = re.sub(r'\s\s+|[,.]\s*$', ' ', reviewer_text).strip()
        if not len(reviewer_text):
            return None, None

        reviewer_list = ChangeLogEntry._split_reviewer_names(reviewer_text)

        # Get rid of "reviewers" like "even though this is just a..." in "Reviewed by Sam Weinig, even though this is just a..."
        # and "who wrote the original code" in "Noam Rosenthal, who wrote the original code"
        reviewer_list = [reviewer for reviewer in reviewer_list if not re.match(r'^who\s|^([a-z]+(\s+|\.|$)){6,}$', reviewer)]

        return reviewer_text, reviewer_list

    @classmethod
    def _split_reviewer_names(cls, text):
        return re.split(ChangeLogEntry.split_names_regexp, text)

    @classmethod
    def _split_author_names_with_emails(cls, text):
        regex = '>' + ChangeLogEntry.split_names_regexp
        names = re.split(regex, text)
        if len(names) > 1:
            names = [name + ">" for name in names[:-1]] + [names[-1]]
        return names

    def _fuzz_match_reviewers(self, reviewers_text_list):
        if not reviewers_text_list:
            return []
        list_of_reviewers = [self._committer_list.contributors_by_fuzzy_match(reviewer)[0] for reviewer in reviewers_text_list]
        # Flatten lists and get rid of any reviewers with more than one candidate.
        return [reviewers[0] for reviewers in list_of_reviewers if len(reviewers) == 1]

    @classmethod
    def _parse_author_name_and_email(cls, author_name_and_email):
        match = re.match(r'(?P<name>.+?)\s+<(?P<email>[^>]+)>', author_name_and_email)
        return {'name': match.group("name"), 'email': match.group("email")}

    @classmethod
    def _parse_author_text(cls, text):
        if not text:
            return []
        authors = cls._split_author_names_with_emails(text)
        assert(authors and len(authors) >= 1)
        return [cls._parse_author_name_and_email(author) for author in authors]

    @classmethod
    def _parse_touched_functions(cls, text):
        result = {}
        cur_file = None
        for line in text.splitlines():
            file_match = re.match(cls.touched_files_regexp, line)
            if file_match:
                cur_file = file_match.group("file")
                result[cur_file] = []
            func_match = re.match(cls.touched_functions_regexp, line)
            if func_match and cur_file:
                result[cur_file].append(func_match.group("function"))
        return result

    @classmethod
    def _parse_bug_description(cls, text):
        # Line 3 is the bug description in most cases.
        lines = text.splitlines()
        if len(lines) < 3:
            return None
        found_reviewed = re.search(ChangeLogEntry.reviewed_by_regexp, lines[2], re.IGNORECASE)
        found_reviewed_byless = re.search(ChangeLogEntry.reviewed_byless_regexp, lines[2], re.IGNORECASE)
        found_url = parse_bug_id_from_changelog(lines[2])
        if found_reviewed or found_reviewed_byless or found_url:
            return None
        return lines[2].strip()

    def _parse_entry(self):
        match = re.match(self.date_line_regexp, self._contents, re.MULTILINE)
        if not match:
            _log.warning("Creating invalid ChangeLogEntry:\n%s" % self._contents)

        self._date_line = match.group()
        self._date = match.group("date")
        self._bug_description = self._parse_bug_description(self._contents)

        # FIXME: group("name") does not seem to be Unicode?  Probably due to self._contents not being unicode.
        self._author_text = match.group("authors") if match else None
        self._authors = ChangeLogEntry._parse_author_text(self._author_text)

        self._reviewer_text, self._reviewers_text_list = ChangeLogEntry._parse_reviewer_text(self._contents)
        self._reviewers = self._fuzz_match_reviewers(self._reviewers_text_list)
        self._author = self._committer_list.contributor_by_email(self.author_email()) or self._committer_list.contributor_by_name(self.author_name())

        self._touched_files = re.findall(self.touched_files_regexp, self._contents, re.MULTILINE)
        self._touched_functions = self._parse_touched_functions(self._contents)

    def date_line(self):
        return self._date_line

    def date(self):
        return self._date

    def author_text(self):
        return self._author_text

    def revision(self):
        return self._revision

    def author_name(self):
        return self._authors[0]['name']

    def author_email(self):
        return self._authors[0]['email']

    def author(self):
        return self._author  # Might be None

    def authors(self):
        return self._authors

    # FIXME: Eventually we would like to map reviwer names to reviewer objects.
    # See https://bugs.webkit.org/show_bug.cgi?id=26533
    def reviewer_text(self):
        return self._reviewer_text

    # Might be None, might also not be a Reviewer!
    def reviewer(self):
        return self._reviewers[0] if len(self._reviewers) > 0 else None

    def reviewers(self):
        return self._reviewers

    def has_valid_reviewer(self):
        if self._reviewers_text_list:
            for reviewer in self._reviewers_text_list:
                reviewer = self._committer_list.reviewer_by_name(reviewer)
                if reviewer:
                    return True
        return bool(re.search("unreviewed", self._contents, re.IGNORECASE))

    def contents(self):
        return self._contents

    def bug_id(self):
        return parse_bug_id_from_changelog(self._contents)

    def bug_description(self):
        return self._bug_description

    def touched_files(self):
        return self._touched_files

    # Returns a dict from file name to lists of function names.
    def touched_functions(self):
        return self._touched_functions

    def touched_files_text(self):
        match = re.search(self.touched_files_regexp, self._contents, re.MULTILINE)
        return self._contents[match.start():].lstrip("\n\r") if match else ""

    # Determine if any text has been added to the section on touched files
    def is_touched_files_text_clean(self):
        file_line_end = r"( (Added|Removed|(Copied|Renamed) from [A-Za-z0-9_\-./\\]+).)?$"
        for line in self.touched_files_text().splitlines():
            if re.match(self.touched_files_regexp + file_line_end, line):
                continue
            if re.match(self.touched_functions_regexp + "$", line):
                continue
            return False
        return True


# FIXME: Various methods on ChangeLog should move into ChangeLogEntry instead.
class ChangeLog(object):

    def __init__(self, path, filesystem=None):
        self.path = path
        self._filesystem = filesystem or FileSystem()

    _changelog_indent = " " * 8

    @classmethod
    def parse_latest_entry_from_file(cls, changelog_file):
        try:
            return next(cls.parse_entries_from_file(changelog_file))
        except StopIteration:
            return None

    svn_blame_regexp = re.compile(r'^(\s*(?P<revision>\d+) [^ ]+)\s*(?P<line>.*?\n)')

    @classmethod
    def _separate_revision_and_line(cls, line):
        match = cls.svn_blame_regexp.match(line)
        if not match:
            return None, line
        return int(match.group('revision')), match.group('line')

    @classmethod
    def parse_entries_from_file(cls, changelog_file):
        """changelog_file must be a file-like object which returns
        unicode strings, e.g. from StringIO(unicode()) or
        fs.open_text_file_for_reading()"""
        date_line_regexp = re.compile(ChangeLogEntry.date_line_regexp)
        rolled_over_regexp = re.compile(ChangeLogEntry.rolled_over_regexp)

        # The first line should be a date line.
        revision, first_line = cls._separate_revision_and_line(changelog_file.readline())
        assert(isinstance(first_line, unicode))
        if not date_line_regexp.match(cls.svn_blame_regexp.sub('', first_line)):
            raise StopIteration

        entry_lines = [first_line]
        revisions_in_entry = {revision: 1} if revision != None else None
        for line in changelog_file:
            if revisions_in_entry:
                revision, line = cls._separate_revision_and_line(line)

            if rolled_over_regexp.match(line):
                break

            if date_line_regexp.match(line):
                most_probable_revision = max(revisions_in_entry, key=revisions_in_entry.__getitem__) if revisions_in_entry else None
                # Remove the extra newline at the end
                yield ChangeLogEntry(''.join(entry_lines[:-1]), revision=most_probable_revision)
                entry_lines = []
                revisions_in_entry = {revision: 0}

            entry_lines.append(line)
            if revisions_in_entry:
                revisions_in_entry[revision] = revisions_in_entry.get(revision, 0) + 1

        most_probable_revision = max(revisions_in_entry, key=revisions_in_entry.__getitem__) if revisions_in_entry else None
        yield ChangeLogEntry(''.join(entry_lines[:-1]), revision=most_probable_revision)

    def latest_entry(self):
        # ChangeLog files are always UTF-8, we read them in as such to support Reviewers with unicode in their names.
        changelog_file = self._filesystem.open_text_file_for_reading(self.path)
        try:
            return self.parse_latest_entry_from_file(changelog_file)
        finally:
            changelog_file.close()

    # _wrap_line and _wrap_lines exist to work around
    # http://bugs.python.org/issue1859

    def _wrap_line(self, line):
        return textwrap.fill(line,
                             width=70,
                             initial_indent=self._changelog_indent,
                             # Don't break urls which may be longer than width.
                             break_long_words=False,
                             subsequent_indent=self._changelog_indent)

    # Workaround as suggested by guido in
    # http://bugs.python.org/issue1859#msg60040

    def _wrap_lines(self, message):
        lines = [self._wrap_line(line) for line in message.splitlines()]
        return "\n".join(lines)

    def update_with_unreviewed_message(self, message):
        first_boilerplate_line_regexp = re.compile(
                r"%sNeed a short description \(OOPS!\)\." % self._changelog_indent)
        removing_boilerplate = False
        result = StringIO()
        with self._filesystem.open_text_file_for_reading(self.path) as file:
            for line in file:
                if first_boilerplate_line_regexp.search(line):
                    message_lines = self._wrap_lines(message)
                    result.write(first_boilerplate_line_regexp.sub(message_lines, line))
                    # Remove all the ChangeLog boilerplate, except the first line (date, name, e-mail).
                    removing_boilerplate = True
                elif removing_boilerplate:
                    if re.search("^[1-9]", line):  # each changelog entry is preceded by a date
                        removing_boilerplate = False

                if not removing_boilerplate:
                    result.write(line)
        self._filesystem.write_text_file(self.path, result.getvalue())

    def set_reviewer(self, reviewer):
        latest_entry = self.latest_entry()
        latest_entry_contents = latest_entry.contents()
        reviewer_text = latest_entry.reviewer()
        found_nobody = re.search(r"NOBODY\s*\(OOPS!\)", latest_entry_contents, re.MULTILINE)
        found_reviewer_or_unreviewed = latest_entry.has_valid_reviewer()
        if not found_nobody and not found_reviewer_or_unreviewed and not reviewer_text:
            bug_url_number_of_items = len(re.findall(config_urls.bug_url_long, latest_entry_contents, re.MULTILINE))
            bug_url_number_of_items += len(re.findall(config_urls.bug_url_short, latest_entry_contents, re.MULTILINE))
            result = StringIO()
            with self._filesystem.open_text_file_for_reading(self.path) as file:
                for line in file:
                    found_bug_url = re.search(config_urls.bug_url_long, line)
                    if not found_bug_url:
                        found_bug_url = re.search(config_urls.bug_url_short, line)
                    result.write(line)
                    if found_bug_url:
                        if bug_url_number_of_items == 1:
                            result.write("\n        Reviewed by %s.\n" % reviewer)
                        bug_url_number_of_items -= 1
            self._filesystem.write_text_file(self.path, result.getvalue())
        else:
            data = self._filesystem.read_text_file(self.path)
            newdata = data.replace("NOBODY (OOPS!)", reviewer)
            self._filesystem.write_text_file(self.path, newdata)

    def set_short_description_and_bug_url(self, short_description, bug_url):
        result = StringIO()
        with self._filesystem.open_text_file_for_reading(self.path) as file:
            short_description_placeholder = "Need a short description (OOPS!)."
            bug_url_placeholder = "Need the bug URL (OOPS!)."
            for line in file:
                stripped = line.strip()
                if stripped == short_description_placeholder:
                    line = self._changelog_indent + short_description + "\n"
                if stripped == bug_url_placeholder:
                    line = self._changelog_indent + bug_url + "\n"
                result.write(line)
        self._filesystem.write_text_file(self.path, result.getvalue())

    def delete_entries(self, num_entries):
        date_line_regexp = re.compile(ChangeLogEntry.date_line_regexp)
        rolled_over_regexp = re.compile(ChangeLogEntry.rolled_over_regexp)
        entries = 0
        result = StringIO()
        with self._filesystem.open_text_file_for_reading(self.path) as file:
            for line in file:
                if date_line_regexp.match(line):
                    entries += 1
                elif rolled_over_regexp.match(line):
                    entries = num_entries + 1
                if entries > num_entries:
                    result.write(line)
        self._filesystem.write_text_file(self.path, result.getvalue())

    def prepend_text(self, text):
        data = self._filesystem.read_text_file(self.path)
        self._filesystem.write_text_file(self.path, text + data)
