#!/usr/bin/python2.7
#
# Univention Appliance Docker Container
#  restoring previously saved data (before app installation)
#
# Copyright 2015-2020 Univention GmbH
#
# https://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
# <https://www.gnu.org/licenses/>.

from optparse import OptionParser
import os
import shutil
import univention.config_registry
import traceback

BLACKLIST_UCR_VARIABLES = [
	'version/version',
	'version/erratalevel',
	'version/patchlevel',
]


# Helper function to copy all meta data of a file or directory
def copy_permissions(src, dest):
	s_stat = os.stat(src)
	os.chown(dest, s_stat.st_uid, s_stat.st_gid)
	shutil.copymode(src, dest)
	shutil.copystat(src, dest)
	d_stat = os.stat(dest)


def restore_files(source_dir):
	if not os.path.exists(source_dir):
		return
	for (path, dirs, files) in os.walk(source_dir):
		for d in dirs:
			r_path = path.replace(source_dir, '/', 1)
			dest = os.path.join(r_path, d)
			if not os.path.exists(dest):
				os.makedirs(dest)
			src = os.path.join(path, d)
			copy_permissions(src, dest)
		for i in files:
			src = os.path.join(path, i)
			dest = src.replace(source_dir, '', 1)
			if os.path.islink(src):
				linkto = os.readlink(src)
				if os.path.exists(dest) or os.path.islink(dest):
					print 'rm %s' % dest
					os.remove(dest)
				print 'ln -sf %s %s' % (linkto, dest)
				os.symlink(linkto, dest)
			else:
				print 'cp %s %s' % (src, dest)
				shutil.copy(src, dest)
				copy_permissions(src, dest)


def restore_ucr_layer(ucr_file, options):
	if not os.path.exists(ucr_file):
		return
	f = open(ucr_file, "r")
	vv = []
	for v in f.readlines():
		if v.startswith('#') or ': ' not in v:
			continue
		key, value = v.split(': ', 1)
		if key not in BLACKLIST_UCR_VARIABLES:
			vv.append('%s=%s' % (key, value.strip()))
	if vv:
		print vv
		univention.config_registry.handler_set(vv, opts=options)


if __name__ == '__main__':
	parser = OptionParser('%prog [options]')
	parser.add_option('--app', dest='app', help='App ID')
	parser.add_option('--app-version', dest='app_version', help='Version of App')
	parser.add_option('--error-file', dest='error_file', help='Name of Error File')
	opts, args = parser.parse_args()

	conf_dir = '/var/lib/univention-appcenter/apps/%s/conf/' % opts.app
	source_dir = '/var/lib/univention-appcenter/apps/%s/conf/files' % opts.app

	try:
		restore_files(source_dir)

		print '** Restore forced UCR layer:'
		restore_ucr_layer(os.path.join(conf_dir, 'base-forced.conf'), {'force': True})
		print '** Restore ldap UCR layer'
		restore_ucr_layer(os.path.join(conf_dir, 'base-ldap.conf'), {'ldap-policy': True})
		print '** Restore normal UCR layer:'
		restore_ucr_layer(os.path.join(conf_dir, 'base.conf'), {})
	except:
		traceback.print_exc()
		if opts.error_file:
			error_file = open(opts.error_file, 'a+')
			traceback.print_exc(file=error_file)
			error_file.close()
		raise
