#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
#
# Univention Configuration Registry
"""Install config registry script."""
#
# Copyright 2004-2014 Univention GmbH
#
# http://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <http://www.gnu.org/licenses/>.

import os
import sys
import univention.config_registry
from univention.debhelper import doIt, binary_packages
from optparse import OptionParser
try:
	from shlex import quote
except ImportError:
	from pipes import quote

def tmpDir(package):
	"""Name of the packages build directory."""
	return 'debian/'+package

def extFile(package, ext):
	"""Name of a package configuration file."""
	return 'debian/'+package+'.'+ext

def srcPath(file):
	"""Find file in source directory."""
	f = 'conffiles/'+file
	if os.path.exists(f): return f
	f = file
	if os.path.exists(f): return f
	if file.startswith('etc/'):
		f = 'conffiles/'+file[4:]
		if os.path.exists(f): return f
	print >>sys.stderr, "file %s was not found" % file
	sys.exit(1)

def destPath(file, package, type='files'):
	"""File name for a UCR file inside the packages build directory."""
	return tmpDir(package)+'/etc/univention/templates/'+type+'/'+file

def destDir(file, package, type='files'):
	"""Directory name for a UCR file inside the packages build directory."""
	return tmpDir(package)+'/etc/univention/templates/'+type+'/'+os.path.dirname(file)

def typeDir(type):
	"""Name for the subdirectory for a UCR file."""
	if type == 'script':
		return 'script'
	else:
		return 'file'

def do_package(package):
	"""Install all files related to one package."""
	n_ucr = extFile(package, 'univention-config-registry')
	if not os.path.exists(n_ucr):
		return

	f_ucr = open(n_ucr, 'r')

	for item in univention.config_registry.parseRfc822(f_ucr.read()):
		typ = item['Type'][0]
		if typ == 'file':
			f = item['File'][0]
			doIt('install', '-d', destDir(f, package))
			doIt('cp', '-a', srcPath(f), destPath(f, package))
			for key in ('Preinst', 'Postinst'):
				if key in item:
					mod = item[key][0]
					doIt('install', '-d', destDir(mod, package, 'modules'))
					doIt('cp', '-a', srcPath(mod), destPath(mod, package, 'modules'))
		elif typ == 'subfile':
			f = item['Subfile'][0]
			doIt('install', '-d', destDir(f, package))
			doIt('cp', '-a', srcPath(f), destPath(f, package))
		elif typ == 'multifile':
			f = item['Multifile'][0]
			if os.path.exists(f):
				doIt('install', '-d', destDir(f, package))
				doIt('cp', '-a', srcPath(f), destPath(f, package))
			for key in ('Preinst', 'Postinst'):
				if key in item:
					mod = item[key][0]
					doIt('install', '-d', destDir(mod, package, 'modules'))
					doIt('cp', '-a', srcPath(mod), destPath(mod, package, 'modules'))
		elif typ == 'script':
			f = item['Script'][0]
			doIt('install', '-d', destDir(f, package, 'scripts'))
			doIt('cp', '-a', srcPath(f), destPath(f, package, 'scripts'))
			doIt('chmod', 'a+x', destPath(f, package, 'scripts'))
		elif typ == 'module':
			f = item['Module'][0]
			doIt('install', '-d', destDir(f, package, 'modules'))
			doIt('cp', '-a', srcPath(f), destPath(f, package, 'modules'))
		else:
			print >>sys.stderr, 'Unknown type: %s' % typ
			return

	f_ucr.close()

	doIt('install', '-d', destDir('', package, 'info'))
	doIt('install', '-m644', n_ucr, destPath(package+'.info', package, 'info'))
	mapping_file = extFile( package, 'univention-config-registry-mapping')
	if os.path.exists(mapping_file):
		doIt('install', '-d', destDir('', package, 'mapping'))
		doIt('install', '-m644', mapping_file, destPath(package+'.univention-config-registry-mapping', package, 'mapping'))

	data = {
			'pkg': quote(package),
			'info': quote("/etc/univention/templates/info/%s.info" % package),
			'removed': quote("/etc/univention/templates/removed/%s.info" % package),
			}

	f_preinst = open(extFile(package, 'preinst.debhelper'), 'a')
	f_preinst.write('# Automatically added by univention-install-config-registry\n')
	f_preinst.write('if [ "$1" = "install" ] ; then\n')
	f_preinst.write('  [ -e %(removed)s ] && [ ! -e %(info)s ] && mv %(removed)s %(info)s || true\n' % data)
	f_preinst.write('fi\n')
	f_preinst.write('# End automatically added section\n')
	f_preinst.close()

	f_postinst = open(extFile(package, 'postinst.debhelper'), 'a')
	f_postinst.write('# Automatically added by univention-install-config-registry\n')
	f_postinst.write('if [ "$1" = "abort-remove" ]; then\n')
	f_postinst.write('  [ -e %(removed)s ] && mv %(removed)s %(info)s || true\n' % data)
	f_postinst.write('fi\n')
	f_postinst.write('[ -x /usr/sbin/univention-config-registry ] && univention-config-registry register %(pkg)s || true\n' % data)
	f_postinst.write('# End automatically added section\n')
	f_postinst.close()

	f_prerm = open(extFile(package, 'prerm.debhelper'), 'a')
	f_prerm.write('# Automatically added by univention-install-config-registry\n')
	f_prerm.write('if [ "$1" = "remove" ] && [ -e %(info)s ] ; then\n' % data)
	f_prerm.write('  [ -x /usr/sbin/univention-config-registry ] && univention-config-registry unregister %(pkg)s || true\n' % data)
	f_prerm.write('  mv %(info)s %(removed)s || true\n' % data)
	f_prerm.write('fi\n')
	f_prerm.write('# End automatically added section\n')
	f_prerm.close()

	doIt('perl', '-e', 'use Debian::Debhelper::Dh_Lib;addsubstvar("%s", "misc:Depends", "univention-config (>= 7.0.25)");' % package)

def main():
	"""Install config registry script."""
	usage = "%prog"
	epilog = '''univention-install-config-registry is a debhelper like programm
to install Univention Config Registry (UCR) related templates, scripts, and
modules into the package build directories.

The UCR descriptions debian/*.univention-config-registry go to /etc/univention/templates/info/*.info.

The UCR templates from conffiles/* go to /etc/univention/templates/files/.

The scripts from conffiles/* go to /etc/univention/templates/scripts/.

The modules from conffiles/* go to /etc/univention/templates/modules/.

The mapping files debian/*.univention-config-registry-mapping go to /etc/univention/templates/mapping/.
	'''
	parser = OptionParser(usage=usage, epilog=epilog)
	parser.add_option('-v', '--verbose',
			dest='verbose', action='store_true',
			help='Verbose mode: show all commands that modify the package build directory.')
	options, args = parser.parse_args()
	if options.verbose:
		os.environ['DH_VERBOSE'] = '1'
	if args:
		parser.error('No argument expected')

	try:
		for package in binary_packages():
			do_package(package)
	except (LookupError, IOError), ex:
		print >> sys.stderr, ex
		sys.exit(1)

	doIt("univention-install-config-registry-info")
	doIt("univention-install-service-info")

if __name__ == '__main__':
	main()
