#!/usr/share/ucs-test/runner python
## -*- coding: utf-8 -*-
## desc: check group membership in new context
## tags: [apptest]
## exposure: dangerous
## packages:
##   - univention-ox (>= 8.1.0-72)
##   - open-xchange-authentication-ucs (>= 7.8.4-0)
## bugs: [43209]

import univention.testing.utils as utils
import univention.testing.udm as testing_udm
import univention.testing.ucr as testing_ucr
import univention.testing.strings as uts
import essential.common
import subprocess


class Bunch(object):
	"""
	>>> y = Bunch(foo=42, bar='TEST')
	>>> print repr(y.foo), repr(y.bar)
	42 'TEST'

	>>> x = Bunch()
	>>> x.a = 4
	>>> print x.a
	4
	"""
	def __init__(self, **kwds):
		self.__dict__.update(kwds)

	def __str__(self):
		result = []
		for key, value in self.__dict__.iteritems():
			result.append('%s=%r' % (key, value))
		return 'Bunch(' + ', '.join(result) + ')'

	def __repr__(self):
		return str(self)


with testing_udm.UCSTestUDM() as udm, \
		testing_ucr.UCSTestConfigRegistry() as ucr, \
		essential.common.OXTestEnv() as oxenv, \
		essential.common.OXTestEmptyQueue():

	context_id = uts.random_int(100, 300)
	mail_domain = ucr.get('mail/hosteddomains').split()[-1].strip()
	ldap_base = ucr.get('ldap/base')

	oxenv.create_context(context_id)
	oxenv.check_if_context_exists_in_ldap(context_id)
	oxenv.check_if_context_exists_in_ox(context_id)

	users = []
	for user_context_id in [10, context_id]:
		print('*** Creating user in OX context {}...'.format(user_context_id))
		users.append(Bunch())
		users[-1].password = uts.random_string()
		users[-1].context_id = user_context_id
		users[-1].dn, users[-1].username = udm.create_user(
			mailPrimaryAddress='{}@{}'.format(uts.random_username(), mail_domain),
			password=users[-1].password,
			isOxUser='OK',
			oxContext=user_context_id)

		oxenv.check_if_user_exists_in_context(users[-1].username, user_context_id)
		oxenv.check_if_user_can_login(users[-1].username, users[-1].password)

	print('*** Creating group in all OX contexts (no context specified)...')
	group1 = Bunch()
	group1.name = uts.random_username()
	group1.dn, group1.name = udm.create_group(name=group1.name, isOxGroup='OK')
	for user in users:
		udm.modify_object('users/user', dn=user.dn, append={'groups': [group1.dn]})
		# check if group exists in both contexts (10 + context_id) and if the user
		# of that context is member of the new group.
		oxenv.check_if_group_exists_in_context(group1.name, user.context_id, [user.username])

	print('*** Creating group in OX context {}...'.format(context_id))
	group2 = Bunch()
	group2.name = uts.random_username()
	group2.dn, group2.name = udm.create_group(name=group2.name, isOxGroup='OK', oxContext=context_id)
	udm.modify_object('users/user', dn=users[-1].dn, append={'groups': [group2.dn]})
	oxenv.check_if_group_exists_in_context(group2.name, context_id, [users[-1].username])
	# check if group is created only in given context and not e.g. in default context
	if oxenv.check_if_group_exists_in_context(group2.name, essential.common.ox_default_context, usernames=None, raise_exception=False):
		utils.fail('Group {} unexpectedly found in default context {}'.format(group2.name, essential.common.ox_default_context))

	# create new/second context
	context_id2 = uts.random_int(300, 400)
	print('*** Creating second/new context {} ...'.format(context_id2))
	oxenv.create_context(context_id2)
	oxenv.check_if_context_exists_in_ldap(context_id2)
	oxenv.check_if_context_exists_in_ox(context_id2)

	print('*** Manually triggering sync of listener queue...')
	cmd_proc = subprocess.Popen(
		['/usr/share/univention-ox/process-listener'],
		stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
	cmd_out, cmd_err = cmd_proc.communicate()
	print('process-listener EXITCODE={}  STDOUT=\n{}\nSTDERR=\n{}\n'.format(cmd_proc.wait(), cmd_out, cmd_err))
	print('*** Check if group 1 {!r} with no context set is also present in context {}...'.format(group1.name, context_id2))
	oxenv.check_if_group_exists_in_context(group1.name, context_id2)

	# cleanup UDM objects 1st
	for user in users:
		udm.remove_object('users/user', dn=user.dn)
	for group in [group1, group2]:
		udm.remove_object('groups/group', dn=group.dn)
