import os

import pygit2

from .base import Merger


class AcceptMine(Merger):
    def _create_local_copy(self, branch_name, new_branch):
        old_branch = self.repository.lookup_branch(branch_name,
                                                   pygit2.GIT_BRANCH_LOCAL)
        return old_branch.rename(new_branch, True)

    def reload_branch(self, branch, upstream):
        remote = self.repository.lookup_branch("%s/%s" % (upstream, branch),
                                               pygit2.GIT_BRANCH_REMOTE)
        remote_commit = remote.get_object()

        local = self.repository.create_branch(branch, remote_commit)
        ref = self.repository.lookup_reference("refs/heads/%s" % branch)
        self.repository.checkout(ref, strategy=pygit2.GIT_CHECKOUT_FORCE)

        return local

    def __call__(self, local_branch, remote_branch, upstream):
        # create local copy
        local_copy = self._create_local_copy(local_branch, "merging_local")

        # reload branch from remote
        local = self.reload_branch(local_branch, upstream)

        # get diverge commits
        diverge_commits = self.find_diverge_commits(local_copy, local)

        reference = "refs/heads/%s" % local_branch
        self.repository.checkout(reference,
                                 strategy=pygit2.GIT_CHECKOUT_FORCE)

        # actual merging
        for commit in diverge_commits.first_commits:
            print "Want to merge this:", commit.message
            self.repository.merge(commit.hex)

            # resolve conflicts
            self.solve_conflicts(self.repository.index.conflicts)
            print "conflicte %s" % self.repository.index.conflicts

            # create new commit
            ref = self.repository.lookup_reference(reference)
            message = "merging: %s" % commit.message
            parents = [ref.target, commit.id]
            new_commit = self.repository.commit(message, self.author,
                                                self.commiter, ref=reference,
                                                parents=parents)
            # if index is not empty
            if new_commit is not None:
                self.repository.create_reference(reference,
                                                 new_commit, force=True)

            # checkout on new head
            self.repository.checkout(reference,
                                     strategy=pygit2.GIT_CHECKOUT_FORCE)
            # cleanup after merge
            self.repository.state_cleanup()

        self.repository.checkout(reference,
                                 strategy=pygit2.GIT_CHECKOUT_FORCE)
        # delete merging_local
        ref = self.repository.lookup_reference("refs/heads/merging_local")
        ref.delete()

    def solve_conflicts(self, conflicts):
        if conflicts:
            for common, theirs, ours in conflicts:
                # if we deleted the file and they didn't, remove the file
                if not ours and theirs:
                    self.repository.index.remove(theirs.path)
                # if they deleted the file and we didn't, add the file
                elif ours and not theirs:
                    self.repository.index.add(ours.path)
                # otherwise, overwrite all file with our content
                else:
                    with open(self._full_path(ours.path), "w") as f:
                        f.write(self.repository.get(ours.id).data)
                    self.repository.index.add(ours.path)

    def _full_path(self, partial):
        if partial.startswith("/"):
            partial = partial[1:]
        path = os.path.join(self.repo_path, partial)

        return path

@@ -72,16 +72,563 @@
 erger):%0A
+    def _create_remote_copy(self, branch_name, upstream, new_branch):%0A        reference = %22%25s/%25s%22 %25 (upstream, branch_name)%0A        remote = self.repository.lookup_branch(reference,%0A                                               pygit2.GIT_BRANCH_REMOTE)%0A        remote_commit = remote.get_object()%0A%0A        local = self.repository.create_branch(new_branch, remote_commit)%0A        ref = self.repository.lookup_reference(%22refs/heads/%25s%22 %25 new_branch)%0A        self.repository.checkout(ref, strategy=pygit2.GIT_CHECKOUT_FORCE)%0A%0A        return local%0A%0A
     def 
@@ -1435,18 +1435,14 @@
 ate 
-local copy
+copies
 %0A   
@@ -1451,21 +1451,16 @@
    local
-_copy
  = self.
@@ -1509,25 +1509,24 @@
 local%22)%0A
-%0A
         
 # reload
@@ -1521,95 +1521,126 @@
     
-# reload branch from remote%0A        local = self.reload_branch(local_branch, upstream)%0A
+remote = self._create_remote_copy(remote_branch, upstream,%0A                                          %22merging_remote%22)
 %0A   
@@ -1727,20 +1727,16 @@
 ocal
-_copy, local
+, remote
 )%0A%0A 
@@ -1772,28 +1772,32 @@
 s/%25s%22 %25 
-local_branch
+%22merging_remote%22
 %0A       
@@ -2132,128 +2132,128 @@
     
-self.solve_conflicts(self.repository.index.conflicts)%0A            print %22conflicte %25s%22 %25 self.repository.index.conflicts
+print %22conflicte %25s%22 %25 self.repository.index.conflicts%0A            self.solve_conflicts(self.repository.index.conflicts)
 %0A%0A  
@@ -3076,35 +3076,244 @@
 elf.
-repository.state_cleanup()%0A
+cleanup()%0A%0A        ref = self.repository.lookup_reference(reference)%0A        self.repository.create_reference(%22refs/heads/master%22,%0A                                         ref.target,%0A                                         force=True)
 %0A   
@@ -3338,33 +3338,54 @@
 ry.checkout(
+%22
 ref
-erence
+s/heads/%25s%22 %25 local_branch
 ,%0A          
@@ -3567,24 +3567,404 @@
 f.delete()%0A%0A
+        ref = self.repository.lookup_reference(%22refs/heads/merging_remote%22)%0A        ref.delete()%0A%0A    def cleanup(self):%0A        self.repository.state_cleanup()%0A%0A        status = self.repository.status()%0A%0A        # check for uncheckedout deleted files%0A        for path in status:%0A            if path not in self.repository.index:%0A                os.unlink(self._full_path(path))%0A%0A
     def solv

fix #91