# Copyright (c) 2009, 2010 Google Inc. All rights reserved.
# Copyright (c) 2009 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.

import logging
import os
import re
import sys

from optparse import make_option

from webkitpy.tool import steps

from webkitpy.common.checkout.changelog import parse_bug_id_from_changelog
from webkitpy.common.config.committers import CommitterList
from webkitpy.common.system.user import User
from webkitpy.thirdparty.mock import Mock
from webkitpy.tool.commands.abstractsequencedcommand import AbstractSequencedCommand
from webkitpy.tool.comments import bug_comment_from_svn_revision
from webkitpy.tool.grammar import pluralize, join_with_separators
from webkitpy.tool.multicommandtool import Command

_log = logging.getLogger(__name__)


class CommitMessageForCurrentDiff(Command):
    name = "commit-message"
    help_text = "Print a commit message suitable for the uncommitted changes"

    def __init__(self):
        options = [
            steps.Options.git_commit,
        ]
        Command.__init__(self, options=options)

    def execute(self, options, args, tool):
        # This command is a useful test to make sure commit_message_for_this_commit
        # always returns the right value regardless of the current working directory.
        print("%s" % tool.checkout().commit_message_for_this_commit(options.git_commit).message())


class CleanPendingCommit(Command):
    name = "clean-pending-commit"
    help_text = "Clear r+ on obsolete patches so they do not appear in the pending-commit list."

    # NOTE: This was designed to be generic, but right now we're only processing patches from the pending-commit list, so only r+ matters.
    def _flags_to_clear_on_patch(self, patch):
        if not patch.is_obsolete():
            return None
        what_was_cleared = []
        if patch.review() == "+":
            if patch.reviewer():
                what_was_cleared.append(u"%s's review+" % patch.reviewer().full_name)
            else:
                what_was_cleared.append("review+")
        return join_with_separators(what_was_cleared)

    def execute(self, options, args, tool):
        committers = CommitterList()
        for bug_id in tool.bugs.queries.fetch_bug_ids_from_pending_commit_list():
            bug = self._tool.bugs.fetch_bug(bug_id)
            patches = bug.patches(include_obsolete=True)
            for patch in patches:
                flags_to_clear = self._flags_to_clear_on_patch(patch)
                if not flags_to_clear:
                    continue
                message = u"Cleared %s from obsolete attachment %s so that this bug does not appear in http://webkit.org/pending-commit." % (flags_to_clear, patch.id())
                self._tool.bugs.obsolete_attachment(patch.id(), message)


# FIXME: This should be share more logic with AssignToCommitter and CleanPendingCommit
class CleanReviewQueue(Command):
    name = "clean-review-queue"
    help_text = "Clear r? on obsolete patches so they do not appear in the pending-review list."

    def execute(self, options, args, tool):
        queue_url = "http://webkit.org/pending-review"
        # We do this inefficient dance to be more like webkit.org/pending-review
        # bugs.queries.fetch_bug_ids_from_review_queue() doesn't return
        # closed bugs, but folks using /pending-review will see them. :(
        for patch_id in tool.bugs.queries.fetch_attachment_ids_from_review_queue():
            patch = self._tool.bugs.fetch_attachment(patch_id)
            if not patch.review() == "?":
                continue
            attachment_obsolete_modifier = ""
            if patch.is_obsolete():
                attachment_obsolete_modifier = "obsolete "
            elif patch.bug().is_closed():
                bug_closed_explanation = "  If you would like this patch reviewed, please attach it to a new bug (or re-open this bug before marking it for review again)."
            else:
                # Neither the patch was obsolete or the bug was closed, next patch...
                continue
            message = "Cleared review? from %sattachment %s so that this bug does not appear in %s.%s" % (attachment_obsolete_modifier, patch.id(), queue_url, bug_closed_explanation)
            self._tool.bugs.obsolete_attachment(patch.id(), message)


class AssignToCommitter(Command):
    name = "assign-to-committer"
    help_text = "Assign bug to whoever attached the most recent r+'d patch"

    def _patches_have_commiters(self, reviewed_patches):
        for patch in reviewed_patches:
            if not patch.committer():
                return False
        return True

    def _assign_bug_to_last_patch_attacher(self, bug_id):
        committers = CommitterList()
        bug = self._tool.bugs.fetch_bug(bug_id)
        if not bug.is_unassigned():
            assigned_to_email = bug.assigned_to_email()
            _log.info(u"Bug %s is already assigned to %s (%s)." % (bug_id, assigned_to_email, committers.committer_by_email(assigned_to_email)))
            return

        reviewed_patches = bug.reviewed_patches()
        if not reviewed_patches:
            _log.info("Bug %s has no non-obsolete patches, ignoring." % bug_id)
            return

        # We only need to do anything with this bug if one of the r+'d patches does not have a valid committer (cq+ set).
        if self._patches_have_commiters(reviewed_patches):
            _log.info("All reviewed patches on bug %s already have commit-queue+, ignoring." % bug_id)
            return

        latest_patch = reviewed_patches[-1]
        attacher_email = latest_patch.attacher_email()
        committer = committers.committer_by_email(attacher_email)
        if not committer:
            _log.info("Attacher %s is not a committer.  Bug %s likely needs commit-queue+." % (attacher_email, bug_id))
            return

        reassign_message = u"Attachment %s was posted by a committer and has review+, assigning to %s for commit." % (latest_patch.id(), committer.full_name)
        self._tool.bugs.reassign_bug(bug_id, committer.bugzilla_email(), reassign_message)

    def execute(self, options, args, tool):
        for bug_id in tool.bugs.queries.fetch_bug_ids_from_pending_commit_list():
            self._assign_bug_to_last_patch_attacher(bug_id)


class ObsoleteAttachments(AbstractSequencedCommand):
    name = "obsolete-attachments"
    help_text = "Mark all attachments on a bug as obsolete"
    argument_names = "BUGID"
    steps = [
        steps.ObsoletePatches,
    ]

    def _prepare_state(self, options, args, tool):
        return { "bug_id" : args[0] }


class AttachToBug(AbstractSequencedCommand):
    name = "attach-to-bug"
    help_text = "Attach the file to the bug"
    argument_names = "BUGID FILEPATH"
    steps = [
        steps.AttachToBug,
    ]

    def _prepare_state(self, options, args, tool):
        state = {}
        state["bug_id"] = args[0]
        state["filepath"] = args[1]
        return state


class AbstractPatchUploadingCommand(AbstractSequencedCommand):
    def _bug_id(self, options, args, tool, state):
        # Perfer a bug id passed as an argument over a bug url in the diff (i.e. ChangeLogs).
        bug_id = args and args[0]
        if not bug_id:
            changed_files = self._tool.scm().changed_files(options.git_commit)
            state["changed_files"] = changed_files
            bug_id = tool.checkout().bug_id_for_this_commit(options.git_commit, changed_files)
        return bug_id

    def _prepare_state(self, options, args, tool):
        state = {}
        state["bug_id"] = self._bug_id(options, args, tool, state)
        if not state["bug_id"]:
            _log.error("No bug id passed and no bug url found in ChangeLogs.")
            sys.exit(1)
        return state


class Post(AbstractPatchUploadingCommand):
    name = "post"
    help_text = "Attach the current working directory diff to a bug as a patch file"
    argument_names = "[BUGID]"
    steps = [
        steps.ValidateChangeLogs,
        steps.CheckStyle,
        steps.ConfirmDiff,
        steps.ObsoletePatches,
        steps.SuggestReviewers,
        steps.EnsureBugIsOpenAndAssigned,
        steps.PostDiff,
        steps.SubmitToEWS,
    ]


class LandSafely(AbstractPatchUploadingCommand):
    name = "land-safely"
    help_text = "Land the current diff via the commit-queue"
    argument_names = "[BUGID]"
    long_help = """land-safely updates the ChangeLog with the reviewer listed
    in bugs.webkit.org for BUGID (or the bug ID detected from the ChangeLog).
    The command then uploads the current diff to the bug and marks it for
    commit by the commit-queue."""
    show_in_main_help = True
    steps = [
        steps.UpdateChangeLogsWithReviewer,
        steps.ValidateChangeLogs,
        steps.ObsoletePatches,
        steps.EnsureBugIsOpenAndAssigned,
        steps.PostDiffForCommit,
    ]


class HasLanded(AbstractPatchUploadingCommand):
    name = "has-landed"
    help_text = "Check that the current code was successfully landed and no changes remain."
    argument_names = "[BUGID]"
    steps = [
        steps.HasLanded,
    ]


class Prepare(AbstractSequencedCommand):
    name = "prepare"
    help_text = "Creates a bug (or prompts for an existing bug) and prepares the ChangeLogs"
    argument_names = "[BUGID]"
    steps = [
        steps.PromptForBugOrTitle,
        steps.CreateBug,
        steps.SortXcodeProjectFiles,
        steps.PrepareChangeLog,
    ]

    def _prepare_state(self, options, args, tool):
        bug_id = args and args[0]
        return { "bug_id" : bug_id }


class Upload(AbstractPatchUploadingCommand):
    name = "upload"
    help_text = "Automates the process of uploading a patch for review"
    argument_names = "[BUGID]"
    show_in_main_help = True
    steps = [
        steps.ValidateChangeLogs,
        steps.CheckStyle,
        steps.PromptForBugOrTitle,
        steps.CreateBug,
        steps.SortXcodeProjectFiles,
        steps.PrepareChangeLog,
        steps.EditChangeLog,
        steps.ConfirmDiff,
        steps.ObsoletePatches,
        steps.SuggestReviewers,
        steps.EnsureBugIsOpenAndAssigned,
        steps.PostDiff,
        steps.AddRadar,
        steps.SubmitToEWS,
        steps.WPTChangeExport,
    ]
    long_help = """upload uploads the current diff to bugs.webkit.org.
    If no bug id is provided, upload will create a bug.
    If the current diff does not have a ChangeLog, upload
    will prepare a ChangeLog.  Once a patch is read, upload
    will open the ChangeLogs for editing using the command in the
    EDITOR environment variable and will display the diff using the
    command in the PAGER environment variable."""

    def _prepare_state(self, options, args, tool):
        state = {}
        state["bug_id"] = self._bug_id(options, args, tool, state)
        return state


class EditChangeLogs(AbstractSequencedCommand):
    name = "edit-changelogs"
    help_text = "Opens modified ChangeLogs in $EDITOR"
    show_in_main_help = True
    steps = [
        steps.EditChangeLog,
    ]


class PostCommits(Command):
    name = "post-commits"
    help_text = "Attach a range of local commits to bugs as patch files"
    argument_names = "COMMITISH"

    def __init__(self):
        options = [
            make_option("-b", "--bug-id", action="store", type="string", dest="bug_id", help="Specify bug id if no URL is provided in the commit log."),
            make_option("--add-log-as-comment", action="store_true", dest="add_log_as_comment", default=False, help="Add commit log message as a comment when uploading the patch."),
            make_option("-m", "--description", action="store", type="string", dest="description", help="Description string for the attachment (default: description from commit message)"),
            steps.Options.obsolete_patches,
            steps.Options.review,
            steps.Options.request_commit,
            steps.Options.ews,
        ]
        Command.__init__(self, options=options, requires_local_commits=True)

    def _comment_text_for_commit(self, options, commit_message, tool, commit_id):
        comment_text = None
        if (options.add_log_as_comment):
            comment_text = commit_message.body(lstrip=True)
            comment_text += "---\n"
            comment_text += tool.scm().files_changed_summary_for_commit(commit_id)
        return comment_text

    def execute(self, options, args, tool):
        commit_ids = tool.scm().commit_ids_from_commitish_arguments(args)
        if len(commit_ids) > 10:  # We could lower this limit, 10 is too many for one bug as-is.
            _log.error("webkit-patch does not support attaching %s at once.  Are you sure you passed the right commit range?" % (pluralize(len(commit_ids), "patch")))
            sys.exit(1)

        have_obsoleted_patches = set()
        for commit_id in commit_ids:
            commit_message = tool.scm().commit_message_for_local_commit(commit_id)

            # Prefer --bug-id=, then a bug url in the commit message, then a bug url in the entire commit diff (i.e. ChangeLogs).
            bug_id = options.bug_id or parse_bug_id_from_changelog(commit_message.message()) or parse_bug_id_from_changelog(tool.scm().create_patch(git_commit=commit_id))
            if not bug_id:
                _log.info("Skipping %s: No bug id found in commit or specified with --bug-id." % commit_id)
                continue

            if options.obsolete_patches and bug_id not in have_obsoleted_patches:
                state = { "bug_id": bug_id }
                steps.ObsoletePatches(tool, options).run(state)
                have_obsoleted_patches.add(bug_id)

            diff = tool.scm().create_patch(git_commit=commit_id)
            description = options.description or commit_message.description(lstrip=True, strip_url=True)
            comment_text = self._comment_text_for_commit(options, commit_message, tool, commit_id)
            attachment_id = tool.bugs.add_patch_to_bug(bug_id, diff, description, comment_text, mark_for_review=options.review, mark_for_commit_queue=options.request_commit)

            # We only need to submit --no-review patches to EWS as patches posted for review are
            # automatically submitted to EWS by EWSFeeder.
            if not options.review and options.ews:
                state = {'attachment_ids': [attachment_id]}
                steps.SubmitToEWS(tool, options).run(state)


# FIXME: This command needs to be brought into the modern age with steps and CommitInfo.
class MarkBugFixed(Command):
    name = "mark-bug-fixed"
    help_text = "Mark the specified bug as fixed"
    argument_names = "[SVN_REVISION]"

    def __init__(self):
        options = [
            make_option("--bug-id", action="store", type="string", dest="bug_id", help="Specify bug id if no URL is provided in the commit log."),
            make_option("--comment", action="store", type="string", dest="comment", help="Text to include in bug comment."),
            make_option("--open", action="store_true", default=False, dest="open_bug", help="Open bug in default web browser (Mac only)."),
            make_option("--update-only", action="store_true", default=False, dest="update_only", help="Add comment to the bug, but do not close it."),
        ]
        Command.__init__(self, options=options)

    # FIXME: We should be using checkout().changelog_entries_for_revision(...) instead here.
    def _fetch_commit_log(self, tool, svn_revision):
        if not svn_revision:
            return tool.scm().last_svn_commit_log()
        return tool.scm().svn_commit_log(svn_revision)

    def _determine_bug_id_and_svn_revision(self, tool, bug_id, svn_revision):
        commit_log = self._fetch_commit_log(tool, svn_revision)

        if not bug_id:
            bug_id = parse_bug_id_from_changelog(commit_log)

        if not svn_revision:
            match = re.search("^r(?P<svn_revision>\d+) \|", commit_log, re.MULTILINE)
            if match:
                svn_revision = match.group('svn_revision')

        if not bug_id or not svn_revision:
            not_found = []
            if not bug_id:
                not_found.append("bug id")
            if not svn_revision:
                not_found.append("svn revision")
            _log.error("Could not find %s on command-line or in %s."
                  % (" or ".join(not_found), "r%s" % svn_revision if svn_revision else "last commit"))
            sys.exit(1)

        return (bug_id, svn_revision)

    def execute(self, options, args, tool):
        bug_id = options.bug_id

        svn_revision = args and args[0]
        if svn_revision:
            if re.match("^r[0-9]+$", svn_revision, re.IGNORECASE):
                svn_revision = svn_revision[1:]
            if not re.match("^[0-9]+$", svn_revision):
                _log.error("Invalid svn revision: '%s'" % svn_revision)
                sys.exit(1)

        needs_prompt = False
        if not bug_id or not svn_revision:
            needs_prompt = True
            (bug_id, svn_revision) = self._determine_bug_id_and_svn_revision(tool, bug_id, svn_revision)

        _log.info("Bug: <%s> %s" % (tool.bugs.bug_url_for_bug_id(bug_id), tool.bugs.fetch_bug_dictionary(bug_id)["title"]))
        _log.info("Revision: %s" % svn_revision)

        if options.open_bug:
            tool.user.open_url(tool.bugs.bug_url_for_bug_id(bug_id))

        if needs_prompt:
            if not tool.user.confirm("Is this correct?"):
                self._exit(1)

        bug_comment = bug_comment_from_svn_revision(svn_revision)
        if options.comment:
            bug_comment = "%s\n\n%s" % (options.comment, bug_comment)

        if options.update_only:
            _log.info("Adding comment to Bug %s." % bug_id)
            tool.bugs.post_comment_to_bug(bug_id, bug_comment)
        else:
            _log.info("Adding comment to Bug %s and marking as Resolved/Fixed." % bug_id)
            tool.bugs.close_bug_as_fixed(bug_id, bug_comment)


# FIXME: Requires unit test.  Blocking issue: too complex for now.
class CreateBug(Command):
    name = "create-bug"
    help_text = "Create a bug from local changes or local commits"
    argument_names = "[COMMITISH]"

    def __init__(self):
        options = [
            steps.Options.cc,
            steps.Options.cc_radar,
            steps.Options.component,
            make_option("--no-prompt", action="store_false", dest="prompt", default=True, help="Do not prompt for bug title and comment; use commit log instead."),
            make_option("--no-review", action="store_false", dest="review", default=True, help="Do not mark the patch for review."),
            make_option("--request-commit", action="store_true", dest="request_commit", default=False, help="Mark the patch as needing auto-commit after review."),
        ]
        Command.__init__(self, options=options)

    def create_bug_from_commit(self, options, args, tool):
        commit_ids = tool.scm().commit_ids_from_commitish_arguments(args)
        if len(commit_ids) > 3:
            _log.error("Are you sure you want to create one bug with %s patches?" % len(commit_ids))
            sys.exit(1)

        commit_id = commit_ids[0]

        bug_title = ""
        comment_text = ""
        if options.prompt:
            (bug_title, comment_text) = self.prompt_for_bug_title_and_comment()
        else:
            commit_message = tool.scm().commit_message_for_local_commit(commit_id)
            bug_title = commit_message.description(lstrip=True, strip_url=True)
            comment_text = commit_message.body(lstrip=True)
            comment_text += "---\n"
            comment_text += tool.scm().files_changed_summary_for_commit(commit_id)

        diff = tool.scm().create_patch(git_commit=commit_id)
        bug_id = tool.bugs.create_bug(bug_title, comment_text, options.component, diff, "Patch", cc=options.cc, mark_for_review=options.review, mark_for_commit_queue=options.request_commit)

        if bug_id and len(commit_ids) > 1:
            options.bug_id = bug_id
            options.obsolete_patches = False
            # FIXME: We should pass through --no-comment switch as well.
            PostCommits.execute(self, options, commit_ids[1:], tool)

    def create_bug_from_patch(self, options, args, tool):
        bug_title = ""
        comment_text = ""
        if options.prompt:
            (bug_title, comment_text) = self.prompt_for_bug_title_and_comment()
        else:
            commit_message = tool.checkout().commit_message_for_this_commit(options.git_commit)
            bug_title = commit_message.description(lstrip=True, strip_url=True)
            comment_text = commit_message.body(lstrip=True)

        diff = tool.scm().create_patch(options.git_commit)
        bug_id = tool.bugs.create_bug(bug_title, comment_text, options.component, diff, "Patch", cc=options.cc, mark_for_review=options.review, mark_for_commit_queue=options.request_commit)

    def prompt_for_bug_title_and_comment(self):
        bug_title = User.prompt("Bug title: ")
        # FIXME: User should provide a function for doing this multi-line prompt.
        print("Bug comment (hit ^D on blank line to end):")
        lines = sys.stdin.readlines()
        try:
            sys.stdin.seek(0, os.SEEK_END)
        except IOError:
            # Cygwin raises an Illegal Seek (errno 29) exception when the above
            # seek() call is made. Ignoring it seems to cause no harm.
            # FIXME: Figure out a way to get avoid the exception in the first
            # place.
            pass
        comment_text = "".join(lines)
        return (bug_title, comment_text)

    def execute(self, options, args, tool):
        if options.cc_radar:
            if options.cc:
                options.cc = "webkit-bug-importer@group.apple.com,%s" % options.cc
            else:
                options.cc = "webkit-bug-importer@group.apple.com"
        if len(args):
            if (not tool.scm().supports_local_commits()):
                _log.error("Extra arguments not supported; patch is taken from working directory.")
                sys.exit(1)
            self.create_bug_from_commit(options, args, tool)
        else:
            self.create_bug_from_patch(options, args, tool)


class WPTChangeExport(AbstractPatchUploadingCommand):
    name = "wpt-change-export"
    help_text = "Opens a pull request to synchronize any changes in the LayoutTests/imported/w3c/web-platform-tests directory"
    argument_names = "[BUGID]"
    steps = [
        steps.WPTChangeExport,
    ]

    long_help = """Opens a pull request to the w3c/web-platform-tests
    github repo for any changes in the
    LayoutTests/imported/w3c/web-platform-tests directory. This step
    will noop if there are no changes in the web-platform-tests directory.
    The user will be prompted to provide a github username and OAuth token
    the first time this is run.
    """

    def _prepare_state(self, options, args, tool):
        state = {}
        state["bug_id"] = self._bug_id(options, args, tool, state)
        return state
