#! /usr/bin/env python
# -*- coding: utf-8 -*-

import os
import re
import subprocess
import sys

from ansible.callbacks import display, banner


class CallbackModule(object):
	"""Makes sure Ansible is not out of date with branch. Requires ansible-playbook command
	to be ran in locally cloned location.
	 """
  #  env_var_name = 'IGNORE_OUTDATED_GIT_BRANCH'

	msg_out_of_sync = 'OUTDATED GIT BRANCH: Your git branch is out of sync with the ' \
		  'remote branch.  Please update your branch (git pull) before continuing. ' \
		  #' or skip this test by setting the environment ' \
		  #  'variable {0}=yes.'.format(env_var_name)

	msg_not_in_git = 'Get inside the git repository, duh!'

	msg_local_changes = 'You have local changes. Please consider committing them before running the playbook.'

#########
	out_of_sync_re = re.compile(r'Your branch (is behind|and .* have diverged)',
								re.MULTILINE)

	local_changes = re.compile(r'Changes not staged for commit',
								re.MULTILINE)
##########

	def playbook_on_start(self):
		try:
			subprocess.check_output(['git pull'], shell=True, stderr=subprocess.STDOUT)
		except subprocess.CalledProcessError:
			pass

		try:
		    cmnd_output = subprocess.check_output(['git status'], shell=True, stderr=subprocess.STDOUT)
		except subprocess.CalledProcessError as exc:
			if exc.returncode == 128:
				# Git returns error code 128 when not inside the git repo
				display(banner(self.msg_not_in_git), color='bright green')
			sys.exit(1)
		else:
			if self.local_changes.search(cmnd_output):
				display(banner(self.msg_local_changes), color='bright red')

			if self.out_of_sync_re.search(cmnd_output):
				display(banner(self.msg_out_of_sync), color='bright blue')
				sys.exit(1)