#!/usr/bin/env python
# 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 os
import re
import sys

from optparse import make_option

from webkitpy.tool import steps

from webkitpy.common.config.committers import CommitterList
from webkitpy.common.net.bugzilla import parse_bug_id_from_changelog
from webkitpy.common.system.deprecated_logging import error, log
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 AbstractDeclarativeCommand


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

    def __init__(self):
        options = [
            steps.Options.git_commit,
        ]
        AbstractDeclarativeCommand.__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(AbstractDeclarativeCommand):
    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("%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 = "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(AbstractDeclarativeCommand):
    name = "clean-review-queue"
    help_text = "Clear r? on obsolete patches so they do not appear in the pending-commit 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(AbstractDeclarativeCommand):
    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("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("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("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("Attacher %s is not a committer.  Bug %s likely needs commit-queue+." % (attacher_email, bug_id))
            return

        reassign_message = "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 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"]:
            error("No bug id passed and no bug url found in ChangeLogs.")
        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.PostDiff,
    ]


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.PostDiffForCommit,
    ]


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.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.PrepareChangeLog,
        steps.EditChangeLog,
        steps.ConfirmDiff,
        steps.ObsoletePatches,
        steps.SuggestReviewers,
        steps.PostDiff,
    ]
    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(AbstractDeclarativeCommand):
    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,
        ]
        AbstractDeclarativeCommand.__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.
            error("webkit-patch does not support attaching %s at once.  Are you sure you passed the right commit range?" % (pluralize("patch", len(commit_ids))))

        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("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)
            tool.bugs.add_patch_to_bug(bug_id, diff, description, comment_text, mark_for_review=options.review, mark_for_commit_queue=options.request_commit)


# FIXME: This command needs to be brought into the modern age with steps and CommitInfo.
class MarkBugFixed(AbstractDeclarativeCommand):
    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."),
        ]
        AbstractDeclarativeCommand.__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")
            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"))

        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):
                error("Invalid svn revision: '%s'" % svn_revision)

        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("Bug: <%s> %s" % (tool.bugs.bug_url_for_bug_id(bug_id), tool.bugs.fetch_bug_dictionary(bug_id)["title"]))
        log("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?"):
                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("Adding comment to Bug %s." % bug_id)
            tool.bugs.post_comment_to_bug(bug_id, bug_comment)
        else:
            log("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(AbstractDeclarativeCommand):
    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.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."),
        ]
        AbstractDeclarativeCommand.__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:
            error("Are you sure you want to create one bug with %s patches?" % len(commit_ids))

        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: ")
        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 len(args):
            if (not tool.scm().supports_local_commits()):
                error("Extra arguments not supported; patch is taken from working directory.")
            self.create_bug_from_commit(options, args, tool)
        else:
            self.create_bug_from_patch(options, args, tool)
