"""Commands to be used as console scripts for the git-origin project."""

from sys import argv
from os import makedirs, environ
from os.path import join, isabs
from errno import EEXIST
from subprocess import call
from git.repo import Repo
from git.cmd import Git
from git.errors import GitCommandError


notes_ref = "refs/notes/origins"


class Messenger:
    def __init__(self, **kwargs):
        self.__dict__ = kwargs

class Index(object):
    def __init__(self, repo, path=None):
        if path is None:
            path = join(repo.path, "index")
            self.git = repo.git
        else:
            self.git = Git(repo.wd)
            env = {
                "GIT_INDEX_FILE": path,
            }
            if not repo.bare:
                env["GIT_WORK_TREE"] = repo.wd
            self.git.extra["env"] = env

        self.path = path
        self.repo = repo

    def data_update(self, path, data, mode="0644", **kwargs):
        if isabs(path):
            path = path[1:]

        hash = self.repo.git.hash_object(stdin=True, t="blob", w=True,
                                         input=data, path=path)
        self.git.update_index("--cacheinfo", mode, hash, path, **kwargs)

    def checkout(self, wd=None, **kwargs):
        if wd is None:
            git = self.git
        else:
            git = Git(wd)
            git.extra = dict(self.git.extra)
            git.extra["env"]["GIT_WORK_TREE"] = wd
        return git.checkout_index(**kwargs)

    def read_tree(self, *args, **kwargs):
        return self.git.read_tree(*args, **kwargs)

    def write_tree(self, *args, **kwargs):
        return self.git.write_tree(*args, **kwargs)


def _commit(repo, ref="HEAD"):
    id = repo.git.rev_parse(ref, verify=True)
    return repo.commit(id)

def _origins(commit):
    repo = commit.repo
    notes = _commit(repo, notes_ref)
    try:
        blob = notes.tree[commit.id]
    except KeyError:
        return

    return [repo.commit(id.strip()) for id in blob.data.splitlines()]

def checkout_origins(repo):
    index = Index(repo, join(repo.path, "origins-index"))
    index.read_tree(notes_ref)
    index.checkout(join(repo.path, "origins-wd"), a=True, f=True)

def add_origin(repo, commit, origin):
    origins = _origins(commit) or []
    originids = [c.id for c in origins]
    if origin.id in originids:
        return

    origins.append(origin)
    originids.append(origin.id)

    index = Index(repo, join(repo.path, "origins-index"))
    index.read_tree(notes_ref)
    index.data_update(commit.id, "\n".join(originids), add=True)
    newtreeid = index.write_tree()
    newcommitid = repo.git.commit_tree(newtreeid,
                                       "-p", _commit(repo, notes_ref).id,
                                       input="Add origin %s to commit %s" % (origin.id, commit.id))
    repo.git.update_ref(notes_ref, newcommitid)
    return True, origins


# Commands
def origin():
    """Add the supplied commit-ish as an origin on HEAD (or the second supplied commit-ish)."""

    if "GIT_NOTES_REF" in environ:
        del environ["GIT_NOTES_REF"]

    repo = Repo()
    if len(argv) > 1:
        origin = _commit(repo, argv[1])
        try:
            commit = _commit(repo, argv[2])
        except IndexError:
            commit = _commit(repo)

        try:
            if add_origin(repo, commit, origin):
                print("Added origin %s to commit %s" % (origin.id, commit.id))
            else:
                print("Origin already set.")
        except GitCommandError, exc:
            raise SystemExit("Failed to add origin when executing %s:\n%s" % (exc.command, exc.stderr))
    else:
        checkout_origins(repo)

@@ -206,16 +206,45 @@
 rt call%0A
+from sys import exit, stderr%0A
 from git
@@ -359,16 +359,157 @@
 rigins%22%0A
+usage = %22%22%22git-origin ORIGIN %5BCOMMIT%5D%0A%0AORIGIN - Commit to mark as an origin.%0ACOMMIT - Commit which has ORIGIN as an origin (default=HEAD)%22%22%22%0A
 %0A%0Aclass 
@@ -3284,16 +3284,21 @@
 )%0A    if
+ 2 %3C=
  len(arg
@@ -3304,11 +3304,12 @@
 gv) 
-%3E 1
+%3C= 3
 :%0A  
@@ -3723,21 +3723,9 @@
     
-raise SystemE
+e
 xit(
@@ -3817,31 +3817,46 @@
         
-checkout_origins(repo
+print %3E%3Estderr, usage%0A        exit(2
 )%0A

Add usage information.