#!/usr/bin/env python

def insert_template_in_configure_ac(name, is_mozilla = False):
	"""Edits ../configure.ac, inserting the name extension."""
	import os.path
	import re
	import tempfile

	path = os.path.join(os.path.dirname(__file__), '..', 'configure.ac')

	old = open(path)
	new = tempfile.TemporaryFile()

	in_extensions = False
	in_conditionals = False
	done_conditionals = False
	in_config_files = False
	done_config_files = False

	re_extensions = re.compile('all_extensions="(?P<extensions>.*)"')

	re_conditional = re.compile('AM_CONDITIONAL\(ENABLE_.*_EXTENSION')

	re_config_files = re.compile('AC_CONFIG_FILES\(\[')

	conditional_line = 'AM_CONDITIONAL(ENABLE_%s_EXTENSION, echo "$extensions" | egrep \'(^|,)%s($|,)\' > /dev/null)\n' % (name.upper().replace('-', '_'), name)

	config_files_line = 'extensions/%s/Makefile\n' % name
	config_files_line2 = 'extensions/%s/mozilla/Makefile\n' % name

	for line in old:
		line_written = False

		match = re_extensions.match(line)
		if match:
			extensions = match.group('extensions').split(',')
			if name in extensions:
				# This occurs if we use --force and the
				# extension has already been inserted.
				new.close()
				return
			extensions.append(name)
			extensions.sort()
			new.write('all_extensions="%s"\n' % ','.join(extensions))
			line_written = True

		if not done_conditionals:
			if re_conditional.match(line):
				in_conditionals = True

		if in_conditionals:
			if (len(line.strip()) == 0 and not done_conditionals) \
					or line > conditional_line:

				new.write(conditional_line)
				done_conditionals = True
				in_conditionals = False

		if re_config_files.match(line):
			in_config_files = True

		if in_config_files and not done_config_files:
			if (line[:3] == 'ext' and line > config_files_line) \
				or line[:2] == 'po':
					new.write(config_files_line)
					if is_mozilla:
						new.write(config_files_line2)
					done_config_files = True

		if not line_written:
			new.write(line)

	old.close()

	new.seek(0)

	open(path, 'w').write(new.read())

def insert_template_in_makefile_am(name):
	"""Edits extensions/Makefile.am, inserting the name extension."""
	import os.path
	import re
	import tempfile

	path = os.path.join(os.path.dirname(__file__), '..', 'extensions',
			    'Makefile.am')

	old = open(path)
	new = tempfile.TemporaryFile()

	enable_line = 'if ENABLE_%s_EXTENSION' % name.upper().replace('-', '_')

	if_regex = re.compile('if ENABLE_.*_EXTENSION')
	dist_regex = re.compile('DIST_SUBDIRS = (?P<extensions>.*)')

	done = False

	for line in old:
		if not done:
			match = if_regex.match(line)
			if match:
				if line.strip() == enable_line:
					# This occurs if we're on --force and
					# the extension is already here
					return

				if line > enable_line:
					new.writelines((enable_line + '\n',
						        'SUBDIRS += %s\n'
							% name,
						        'endif\n',
						        '\n'))
					done = True

		match = dist_regex.match(line)
		if match:
			if not done:
				new.writelines((enable_line + '\n',
					        'SUBDIRS += %s\n' % name,
					        'endif\n',
					        '\n'))
				done = True

			extensions = match.group('extensions').strip().split(' ')
			if name not in extensions:
				extensions.append(name)
			extensions.sort()
			
			new.write('DIST_SUBDIRS = %s\n' % ' '.join(extensions))
		else:
			new.write(line)

	new.seek(0)

	open(path, 'w').write(new.read())

def copy_template_files(paths, replacements):
	"""Copies files from paths applying replacements to names and contents.

	For example, having replacements of
	{'sample':'gestures','SAMPLE':'GESTURES','Sample':'Gestures'} and
	passing all files in extensions/sample as this function's first
	argument, they files would all move to extensions/gestures and have
	their contents updated.
	"""
	import os

	for path in paths:
		dest = path
		for a, b in replacements.items():
			dest = dest.replace(a, b)

		dir = os.path.dirname(dest)

		if not os.path.exists(dir): os.makedirs(dir)

		r = open(path, 'r')
		w = open(dest, 'w')

		for line in r:
			for a, b in replacements.items():
				line = line.replace(a, b)
			w.write(line)

		r.close()
		w.close()

def copy_sample_template(new_name):
	"""Copies the sample extension (in extensions/sample) to new_name.

	new_name should be the name of the new extension, with words separated
	by dash ('-') characters.
	"""

	import os.path

	t_paths = (
		'ephy-sample-extension.h',
		'ephy-sample-extension.c',
		'Makefile.am',
		'sample.c',
		'sample.xml.in.in',
		)

	paths = []

	root = os.path.normpath(os.path.dirname(__file__) + \
				'/../extensions/sample')

	for path in t_paths:
		paths.append(os.path.join(root, path))

	replacements = {
		'sample.c': 'extension.c',
		'sample.xml.in.in': new_name + '.xml.in.in',
		'libsample': 'lib' + new_name.replace('-', ''),
		'sample/': new_name + '/',
		'sample-': new_name + '-',
		'sample_': new_name.replace('-', '_') + '_',
		'Sample': new_name.title().replace('-', ''),
		'SAMPLE': new_name.upper().replace('-', '_'),
		}

	copy_template_files (paths, replacements)

	insert_template_in_configure_ac(new_name)
	insert_template_in_makefile_am(new_name)

def copy_sample_mozilla_template(new_name):
	"""Copies the extension in extensions/sample-mozilla to new_name.

	new_name should be the name of the new extension, with words separated
	by dash ('-') characters.
	"""

	import os.path

	t_paths = (
		'ephy-sample2-extension.h',
		'ephy-sample2-extension.c',
		'Makefile.am',
		'sample-mozilla.c',
		'sample-mozilla.xml.in.in',
		'mozilla/Makefile.am',
		'mozilla/mozilla-sample.cpp',
		'mozilla/mozilla-sample.h',
		)

	paths = []

	root = os.path.normpath(os.path.dirname(__file__) + \
				'/../extensions/sample-mozilla')

	for path in t_paths:
		paths.append(os.path.join(root, path))

	replacements = {
		'sample-mozilla.c': 'extension.c',
		'sample-mozilla.xml.in.in': new_name + '.xml.in.in',
		'mozilla-sample': 'mozilla-helpers',
		'sample-mozilla/': new_name + '/',
		'libsamplemozilla': 'lib' + new_name.replace('-', ''),
		'sample2-': new_name + '-',
		'sample2_': new_name.replace('-', '_') + '_',
		'Sample2': new_name.title().replace('-', ''),
		'SAMPLE2': new_name.upper().replace('-', '_'),
		}

	copy_template_files (paths, replacements)

	insert_template_in_configure_ac(new_name, True)
	insert_template_in_makefile_am(new_name)

if __name__ == '__main__':
	from optparse import OptionParser

	usage = 'usage: %prog [options] new-name'
	description = 'Copies a sample extension template to new ' + \
		      'subdirectory of extensions/, specified by new_name'
	parser = OptionParser(usage=usage, description=description)
	parser.add_option('-f', '--force', dest='force',
			  action='store_true', default=False,
			  help='Overwrite existing extensions')
	parser.add_option('-m', '--mozilla', dest='use_mozilla',
			  action='store_true', default=False,
			  help='Use Mozilla template')
	(options, args) = parser.parse_args()

	if len(args) != 1:
		parser.error('Wrong number of arguments')

	if options.use_mozilla:
		f = copy_sample_mozilla_template
	else:
		f = copy_sample_template

	import os.path

	root = os.path.normpath(os.path.dirname(__file__) + \
				'/../extensions/' + args[0])

	if os.path.exists(root) and not options.force:
		parser.error('Specified path already exists')

	f(args[0])
