# -*- coding: utf-8 -*-

from fabric.api import cd, env, run, local, task
from fabric.contrib.files import exists
from ..utils import green_alert, red_alert, yellow_alert
from .. import signal

def init():
    if not hasattr(env, 'git_use_reset'):
        env.git_use_reset = False

    if not hasattr(env, 'sed_bsd'):
        env.sed_bsd = True

    if not hasattr(env, 'git_show_delta'):
        env.git_show_delta = False

    if not hasattr(env, 'branch'):
        env.branch = 'master'

    signal.register('deploy.delta.publishing', publish_git_delta)
    signal.register('deploy.head.publishing', publish_git_head)

    signal.register('deploy.reverted', log_reverted_revision)
    signal.register('deploy.started', check_repo)
    signal.register('deploy.updating', update_git_repo)

def publish_git_delta(**kwargs):
    head = _get_remote_head()
    delta_log = _get_delta(head)
    if not delta_log:
        green_alert('No delta.')
        return
    green_alert('Get delta:\n%s' % delta_log)
    signal.emit('git.delta.publishing', head=head, delta_log=delta_log)
def check_repo(**kwargs):
    _check()

def publish_git_head(**kwargs):
    head = _get_remote_head()
    green_alert('Get head: \n%s' % head)
    signal.emit('git.head.publishing', head=head)

def log_reverted_revision(**kwargs):
    head = _get_remote_head()
    green_alert('Rollback to %s' % head)
    signal.emit('git.reverted', head=head)

def update_git_repo(**kwargs):
    if not exists('%(path)s/repo' % env):
        _clone()
    _update()


def _get_remote_head():
    if exists('.git'):
        return run("git rev-parse --short HEAD", quiet=True)


def _get_delta(current_version, upstream='origin', bsd=True):
    if not env.git_show_delta:
        return

    local('/usr/bin/env git fetch -q %s' % upstream)
    return local(
        '/usr/bin/env git log '
        '--reverse '
        '--pretty="%%h %%s: %%b" '
        '--merges %s..%s/master | '

        '/usr/bin/env sed -%s '
        '"s/Merge pull request #([0-9]+) from ([^/]+)\\/[^:]+/#\\1\\/\\2/"'
        % (
            current_version,
            upstream,
            'E' if bsd else 'r'
        ),
        capture=True
    ).decode('utf8')


def _check():
    with cd('%(path)s/repo' % env):
        run('git ls-remote --heads %(repo)s' % env)


def _clone():
    if exists('%(path)s/repo/HEAD'):
        abort('Repo has cloned already!')

    if hasattr(env, 'git_shallow_clone') and env.git_shallow_clone:
        run('git clone --mirror --depth %(git_shallow_clone)s '
            '--no-single-branch %(repo)s %(path)s/repo' % env)
    else:
        run('git clone --mirror %(repo)s %(path)s/repo' % env)


def _update():
    with cd('%(path)s/repo' % env):
        if hasattr(env, 'git_shallow_clone') and env.git_shallow_clone:
            run(
                'git fetch '
                '--depth %(git_shallow_clone)s '
                'origin %(branch)s' % env
            )
        else:
            run('git remote update --prune')

@@ -66,16 +66,23 @@
 al, task
+, abort
 %0Afrom fa
@@ -524,110 +524,29 @@
 loy.
-delta.publishing', publish_git_delta)%0A    signal.register('deploy.head.publishing', publish_git_head)%0A
+started', check_repo)
 %0A   
@@ -580,25 +580,26 @@
 vert
-ed
+ing
 ', log_
+p
 rev
-erted
+ious
 _rev
@@ -633,36 +633,58 @@
 'deploy.
-started', check_repo
+finishing_rollback', log_rollback_revision
 )%0A    si
@@ -738,292 +738,8 @@
 o)%0A%0A
-def publish_git_delta(**kwargs):%0A    head = _get_remote_head()%0A    delta_log = _get_delta(head)%0A    if not delta_log:%0A        green_alert('No delta.')%0A        return%0A    green_alert('Get delta:%5Cn%25s' %25 delta_log)%0A    signal.emit('git.delta.publishing', head=head, delta_log=delta_log)%0A
 def 
@@ -782,24 +782,29 @@
 def 
-publish_git_head
+log_previous_revision
 (**k
@@ -827,111 +827,69 @@
  = _
-get_remote_head()%0A    green_alert('Get head: %5Cn%25s' %25 head)%0A    signal.emit('git.head.publishing', head=
+read_current_revision()%0A    green_alert('Rollback from %25s' %25 
 head
@@ -900,23 +900,23 @@
 ef log_r
-everted
+ollback
 _revisio
@@ -940,31 +940,37 @@
 head = _
-get_remote_head
+read_current_revision
 ()%0A    g
@@ -1008,51 +1008,8 @@
 ead)
-%0A    signal.emit('git.reverted', head=head)
 %0A%0Ade
@@ -1110,16 +1110,79 @@
 pdate()%0A
+    _set_current_version()%0A    _release()%0A    _echo_revision()%0A
 %0A%0Adef _g
@@ -2649,8 +2649,703 @@
 prune')%0A
+%0A%0Adef _release():%0A    with cd('%25(path)s/repo' %25 env):%0A        run('git archive %25(branch)s '%0A            '%7C tar -x -f - -C %25(releases_path)s/%25(new_release)s' %25 env)%0A%0A%0Adef _get_revision():%0A    with cd('%25(path)s/repo' %25 env):%0A        return run(%0A            'git rev-list '%0A            '--max-count=1 '%0A            '--abbrev-commit '%0A            '--abbrev=12 '%0A            '%25(branch)s' %25 env%0A        )%0A%0A%0Adef _echo_revision():%0A    with cd('%25(releases_path)s/%25(new_release)s' %25 env):%0A        run('echo %25(current_version)s %3E%3E REVISION' %25 env)%0A%0A%0Adef _read_current_revision():%0A    return run('cat %25(current_path)s/REVISION' %25 env)%0A%0A%0Adef _set_current_version():%0A    env.current_version = _get_revision()%0A

Refactor git revision.