#!/usr/share/ucs-test/runner python
## -*- coding: utf-8 -*-
## desc: test deletion of users home directory by listener module
## roles: [domaincontroller_slave]
## tags: [apptest, ucsschool]
## bugs: [41989]
## packages: [ucs-school-old-homedirs]
## exposure: dangerous

import os
import time
from pwd import getpwnam
from ldap.filter import escape_filter_chars
from univention.testing import utils
import univention.testing.udm
import univention.testing.ucsschool as utu
from univention.testing.ucs_samba import wait_for_drs_replication
from ucsschool.lib.models import School, User
from essential.importusers_cli_v2 import CLI_Import_v2_Tester


class Test(CLI_Import_v2_Tester):
	def __init__(self):
		self.ou_A = None
		self.ou_B = None
		self.ou_C = None
		super(Test, self).__init__()

	def run(self):
		try:
			with univention.testing.udm.UCSTestUDM() as udm:
				self.udm = udm
				with utu.UCSTestSchool() as schoolenv:
					self.lo = schoolenv.open_ldap_connection()
					self.schoolenv = schoolenv
					self.ou_A.name, self.ou_A.dn = schoolenv.create_ou(name_edudc=self.ucr.get('hostname'))
					self.ou_B.name, self.ou_B.dn = schoolenv.create_ou()
					self.log.info(
						'*** This host is responsible for OU %r, but not for OU %r.',
						self.ou_A.name,
						self.ou_B.name)
					all_local_schools = [school.dn for school in School.get_all(self.lo)]
					self.log.info('*** This hosts school OUs: %r\n\n', all_local_schools)
					if self.ou_B.name in all_local_schools:
						utils.fail('Found OU %r in local schools.' % self.ou_B.name)

					self.test()
					self.log.info('Test was successful.\n\n\n')
		finally:
			self.cleanup()

	def test(self):
		for role in ('student', 'teacher', 'teacher_and_staff'):
			self.log.info('*** Creating user 1 with role %r in OU %r', role, self.ou_A.name)
			kwargs = dict(
				ou_name=self.ou_A.name,
				schools=[self.ou_A.name],
			)
			if role in ['teacher', 'teacher_and_staff']:
				kwargs['is_teacher'] = True
			if role in ['staff', 'teacher_and_staff']:
				kwargs['is_staff'] = True
			username1, userdn1 = self.schoolenv.create_user(**kwargs)

			self.log.info('*** Creating user 2 with role %r in OUs %r', role, [self.ou_A.name, self.ou_B.name])
			kwargs = dict(
				ou_name=self.ou_A.name,
				schools=[self.ou_A.name, self.ou_B.name],
			)
			if role in ['teacher', 'teacher_and_staff']:
				kwargs['is_teacher'] = True
			if role in ['staff', 'teacher_and_staff']:
				kwargs['is_staff'] = True
			username2, userdn2 = self.schoolenv.create_user(**kwargs)
			user1 = User.from_dn(userdn1, None, self.lo)
			user2 = User.from_dn(userdn2, None, self.lo)
			homedir1 = user1.get_udm_object(self.lo)['unixhome']
			homedir2 = user2.get_udm_object(self.lo)['unixhome']
			self.log.debug('homedir1=%r', homedir1)
			self.log.debug('homedir2=%r', homedir2)
			os.makedirs(homedir1, 0711)
			os.makedirs(homedir2, 0711)
			try:
				os.chown(homedir1, getpwnam(username1).pw_uid, getpwnam(username1).pw_gid)
				os.chown(homedir2, getpwnam(username2).pw_uid, getpwnam(username2).pw_gid)
			except KeyError as exc:
				self.log.error("*** getpwnam() failure -> user not found -> probably replication error: %s", exc)
				self.log.error("*** if test fails now, it's because of this")
			if not (os.path.exists(homedir1) and os.path.isdir(homedir1)):
				utils.fail('Homedir 1 %r was not created.' % homedir1)
			else:
				self.log.info("Created homedir 1 %r: %r", homedir1, os.stat(homedir1))
			if not (os.path.exists(homedir2) and os.path.isdir(homedir2)):
				utils.fail('Homedir 2 %r was not created.' % homedir2)
			else:
				self.log.info("Created homedir 2 %r: %r", homedir2, os.stat(homedir2))
			time.sleep(30)

			self.log.info(
				'*** Deleting %r 1 %r, should remove home directory %r on this host...',
				role,
				user1,
				homedir1)
			user1.remove(self.lo)
			utils.wait_for_replication_and_postrun()
			if os.path.exists(homedir1):
				utils.fail('Homedir 1 %r was not removed.' % homedir1)
			self.log.info("OK 1: homedir %r was removed.", homedir1)

			self.log.info(
				'*** Removing %r 2 %r from OU %r, should remove home directory %r on this host...',
				role,
				user2,
				self.ou_A.name,
				homedir2)
			wait_for_drs_replication('cn={}'.format(escape_filter_chars(username2)))
			user2.remove_from_school(self.ou_A.name, self.lo)
			user2.modify(self.lo)
			utils.wait_for_replication_and_postrun()
			if os.path.exists(homedir2):
				utils.fail('Homedir 2 %r was not removed.' % homedir2)
			self.log.info("OK 2: homedir %r was removed.", homedir2)


def main():
	tester = Test()
	try:
		tester.run()
	finally:
		tester.cleanup()


if __name__ == '__main__':
	main()
