import json
import re
import datetime
import time
import os
import os.path
import dulwich.repo
import jenkinscli
import xml.etree.ElementTree as ET
import sys
import argparse
import textwrap

# This script will create jobs for each remote branch found in the repository
# in the current directory. It will also remove the jobs if the branches are
# no longer exiting.
#
# - The branch name pattern can be configured
# - The template job name can be configured
# - A branch is being ignored if the last commit is older than a configurable
#   amount of days
#
# Requirements:
# - Python 2.6 (2.7 should work too)
# - dulwich (install it using # pip install dulwich)
# - py-jenkins-cli (https://github.com/tholewebgods/py-jenkins-cli)
#

BINARY_NAME="syncgit"
VERSION="0.1"

# Default for max. commit age of a branch
DEFAULT_MAX_COMMIT_AGE=30


class Jenkins(object):

	"""
		Jenkins job management.

		- job_tpl -- the exact job name used as a template (this job might/should be disabled)
		- job_name_tpl -- the resulting job name, has to contain one "%s" placeholder that will be replaced with the sanitized branch name
	"""
	def __init__(self, host, cli_jar, ssh_key, job_tpl, job_name_tpl):
		self._jenkins = jenkinscli.JenkinsCli(host, cli_jar, ssh_key)

		self._job_template = job_tpl
		self._job_name_tpl = job_name_tpl


	"""
	Create Job for Git ref name
	"""
	def create_job(self, ref_name):
		# load template and replace placeholder in config
		config_template = self._jenkins.get_job(self._job_template)

		# deserialize
		root = ET.fromstring(config_template)

		xpath = ".//scm/branches/hudson.plugins.git.BranchSpec/name"

		# get branch name config node
		name_element = root.findall(xpath)

		# check if a "name" node has been selected
		if len(name_element) > 0:
			# set branch name config
			name_element[0].text = ref_name
		else:
			raise Exception("Missing Git branch spec config in config template (xpath: %s)" % (xpath))

		# serialize DOM
		config = ET.tostring(root)

		# replace slashes in ref name to  get clean job name and build job name
		filtered_ref_name = ref_name.replace("origin/", "")
		# Python 2.6 does not support flags=..., using (?i)
		filtered_ref_name = re.sub("(?i)[^a-z0-9_-]+", "-", filtered_ref_name)
		job_name = self._job_name_tpl % filtered_ref_name

		print "Creating and enabling job '%s' for branch %s" % (job_name, ref_name)
		self._jenkins.create_job(job_name, config)
		self._jenkins.enable_job(job_name)

	"""
	Remove Job by Git ref name
	"""
	def remove_job(self, ref_name):
		# replace slashes in ref name to  get clean job name and build job name
		filtered_ref_name = ref_name.replace("origin/", "")
		# Python 2.6 does not support flags=..., using (?i)
		filtered_ref_name = re.sub("(?i)[^a-z0-9_-]+", "-", filtered_ref_name)
		job_name = self._job_name_tpl % filtered_ref_name

		print "Removing job '%s' for branch '%s'" % (job_name, ref_name)