
import github
import webapp2
import logging

from GitHubRepo import GitHubRepo
from datamodel import OauthEntry


class MergeEndpoint(webapp2.RequestHandler):

    def options(self):
        """
        xmlhttp first makes an HTTP OPTION request to negotiate access for POST.
        """
        self.response.headers.add_header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Origin')
        self.response.headers.add_header('Access-Control-Allow-Origin', '*')

    def post(self):
        self.response.headers.add_header('Access-Control-Allow-Origin', '*')

        username = self.request.get('username')
        session_token = self.request.get('session_token')
        oauth_entry = OauthEntry.lookup(username, session_token)
        assert oauth_entry is not None
        oauth_token = oauth_entry.access_token

        # Parse the repo name, owner and PR issue number from the referer URL.
        pull_request_url = self.request.headers['Referer']
        split_url = pull_request_url.split('/')
        owner_name = split_url[3]
        repo_name = split_url[4]
        issue_number = int(split_url[6])
        logging.info("owner=%s, repo=%s, issue=%s" % (owner_name, repo_name, issue_number))

        repo = GitHubRepo(oauth_token, owner_name, repo_name)

        pull = repo.repo.get_pull(issue_number)
        head = pull.head.ref
        base = pull.base.ref

        # Merge base into head
        merge_commit = repo.repo.merge(head, base)

        if merge_commit:
            # TODO: Wait for CI build to pass (use git hook)
            tree = merge_commit.commit.tree
        else:
            head_commit = repo.repo.get_commit(pull.head.sha)
            tree = head_commit.commit.tree

        squash_commit_message = "%s\n" % self.request.get('commit_message') + \
                                "\n" \
                                "---\n" \
                                "Squash commit from %s created by Whaler." % pull_request_url
        base_branch = repo.repo.get_git_ref("heads/%s" % base)
        parents = [repo.repo.get_git_commit(base_branch.object.sha)]
        author = self.get_git_author(pull)
        committer = author  # TODO: Might be better if this is the person who presses the button.
        new_commit = repo.repo.create_git_commit(squash_commit_message, tree, parents, author, committer)

        base_branch.edit(new_commit.sha)

        pull.create_issue_comment("Merged via squash commit %s. :whale:" % new_commit.sha)
        pull.edit(state='closed')

        # Delete the merged branch.
        head_branch = repo.repo.get_git_ref("heads/%s" % head)
        head_branch.delete()

    @staticmethod
    def get_git_author(pull_request):
        """
        :rtype: :class:`github.InputGitAuthor.InputGitAuthor`
        """
        user = pull_request.user
        return github.InputGitAuthor(user.name, user.email)

@@ -2167,28 +2167,24 @@
  = self.get_
-git_
 author(pull)
@@ -2208,85 +2208,32 @@
 r = 
-author  # TODO: Might be better if this is the person who presses the button.
+self.get_committer(repo)
 %0A   
@@ -2641,21 +2641,211 @@
     
-@staticmethod
+def get_committer(self, repo):%0A        %22%22%22%0A        :rtype: :class:%60github.InputGitAuthor.InputGitAuthor%60%0A        %22%22%22%0A        user = repo.user%0A        return self.create_git_author(user.name, user.email)%0A
 %0A   
@@ -2853,27 +2853,29 @@
 def get_
-git_
 author(
+self, 
 pull_req
@@ -3019,49 +3019,374 @@
 urn 
-github.InputGitAuthor(user.
+self.create_git_author(user.name, user.email)%0A%0A    @staticmethod%0A    def create_git_author(name, email):%0A        assert 
 name
-, user.email)%0A
+%0A        if not email:%0A            # This passes validation, but does not correctly link to the user.%0A            # TODO: Is there a better way to do this?%0A            email = %22noemail@github.com%22%0A        return github.InputGitAuthor(name, email)

Use a dummy email in the case that the author or committer does not have an email.