# Copyright (c) 2013 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.

from webkitpy.tool.multicommandtool import Command
from webkitpy.common.checkout.scm.git import Git
from webkitpy.common.system.executive import ScriptError


class SetupGitClone(Command):
    name = "setup-git-clone"
    help_text = "Configures a new Git clone for the WebKit development"

    def execute(self, options, args, tool):
        if not isinstance(tool.scm(), Git):
            print("This command only works inside a Git checkout.")
            return

        if tool.scm().has_working_directory_changes():
            print("There are local changes; aborting the command.")
            return

        username, email = self._get_username_and_email(tool)

        # FIXME: We shouldn't be using a private method.
        run_git = tool.scm()._run_git
        run_git(["pull"])
        run_git(["svn", "init", "--prefix=origin/", "-T", "trunk", "https://svn.webkit.org/repository/webkit"])
        run_git(["config", "--replace", "svn-remote.svn.fetch", "trunk:refs/remotes/origin/master"])
        run_git(["svn", "fetch"])

        run_git(["config", "user.name", username])
        run_git(["config", "user.email", email])

        # Better Objective-C diff.
        run_git(["config", "diff.objcpp.xfuncname", "^[-+@a-zA-Z_].*$"])
        run_git(["config", "diff.objcppheader.xfuncname", "^[@a-zA-Z_].*$"])

        run_git(["config", "core.editor", "perl Tools/Scripts/commit-log-editor --regenerate-log"])

        if tool.user.confirm("Do you want to auto-color status, diff, and branch? (y/n)"):
            run_git(["config", "color.status", "auto"])
            run_git(["config", "color.diff", "auto"])
            run_git(["config", "color.branch", "auto"])

        if tool.user.confirm("Do you use a rebase-based workflow? (y=yes; n=no, I use a merge-based workflow)"):
            run_git(["config", "merge.changelog.driver", "perl Tools/Scripts/resolve-ChangeLogs --fix-merged --merge-driver %O %A %B"])
        else:
            run_git(["config", "merge.changelog.driver", "perl Tools/Scripts/resolve-ChangeLogs --fix-merged --merge-driver %O %B %A"])

        if tool.user.confirm("Do you want to append the git branch name to every build? (e.g. WebKitBuild/mybranch/; y/n)"):
            run_git(["config", "core.webKitBranchBuild", "true"])
            print("You can override this option via git config branch.$branchName.webKitBranchBuild (true|false)")

        print("Done")

    def _get_username_and_email(self, tool):
        try:
            original_path = tool.filesystem.abspath(".")

            tool.filesystem.chdir("Tools/Scripts/")
            username = tool.executive.run_and_throw_if_fail(["perl", "-e", "use lib '.'; use VCSUtils; print STDOUT changeLogName();"], quiet=True)
            if not username:
                username = tool.user.prompt("Your name:")

            email = tool.executive.run_and_throw_if_fail(["perl", "-e", "use lib '.'; use VCSUtils; print STDOUT changeLogEmailAddress();"], quiet=True)
            if not email:
                email = tool.user.prompt("Your email address:")

            tool.filesystem.chdir(original_path)

            return (username, email)
        except ScriptError as error:
            # VCSUtils prints useful error messages on failure, we shouldn't hide these
            if error.output:
                print(error.output)
            raise
