#!/usr/share/ucs-test/runner python
## -*- coding: utf-8 -*-
## desc: check attribute synchronization
## tags: [apptest]
## exposure: dangerous
## packages:
##   - univention-ox

import random
import datetime
from csv import DictReader
import univention.testing.udm as testing_udm
import univention.testing.ucr as testing_ucr
import univention.testing.strings as uts
import univention.testing.utils as utils
from essential.common import OXTestEmptyQueue
from univention.ox.api.http.http_api_client import OXHttpApi, LoginError
from univention.ox.wait_for_ox_server import wait_for_ox_server


GLOBAL_CONTACT_FOLDER = 6


wait_for_ox_server()
with testing_udm.UCSTestUDM() as udm, testing_ucr.UCSTestConfigRegistry() as ucr, OXTestEmptyQueue():
	mail_domain = ucr['mail/hosteddomains'].split()[0]
	kwargs = dict()
	birthday = '{}-{:02}-{:02}'.format(random.randint(1900, 2016), random.randint(1, 12), random.randint(1, 27))
	anniversary = '{}-{:02}-{:02}'.format(random.randint(1900, 2016), random.randint(1, 12), random.randint(1, 27))
	suffix = uts.random_string(4)
	email = '{}@{}'.format(uts.random_username(), mail_domain)
	lang = 'de_DE'  # should be random.choice(list(set([l.split('@')[0].split('.')[0] for l in locale.locale_alias.values()])))
	tz = 'Europe/Berlin'  # should be random.choice(pytz.all_timezones) but the syntax class has a limited list
	udm_to_ox = dict()
	with open('/usr/share/univention-ox/attrlist.csv', 'rb') as fp:
		for row in DictReader(fp):
			if row['module'] != 'users/user' or row['mayChange'] != '1':
				continue

			udm_to_ox[row['CLIName']] = row['oxOption'][2:]

			# bad mapping in attrlist.csv or csv-names != http-names
			if row['name'] == 'oxDisplayName':
				udm_to_ox[row['CLIName']] = 'display_name'
			elif row['name'] == 'oxMiddleName':
				udm_to_ox[row['CLIName']] = 'second_name'
			elif row['name'] == 'oxLanguage':
				udm_to_ox[row['CLIName']] = 'locale'
			elif row['name'] == 'oxContextUser':
				udm_to_ox[row['CLIName']] = 'oxContext'
			#elif row['name'] == '':
			# missing in mapping
			udm_to_ox['mailPrimaryAddress'] = 'email1'

			if row['name'] == 'isOxUser':
				kwargs[row['CLIName']] = 'OK'
				continue
			elif row['name'] == 'oxBirthday':
				kwargs[row['CLIName']] = birthday
				continue
			elif row['name'] == 'oxAnniversary':
				kwargs[row['CLIName']] = anniversary
				continue
			else:
				pass

			if row['syntax'] == 'string':
				kwargs[row['CLIName']] = '{}{}'.format(row['name'], suffix)
			elif row['syntax'] == 'emailAddress':
				kwargs[row['CLIName']] = email
			elif row['syntax'] == 'OkOrNot':
				kwargs[row['CLIName']] = 'OK'
			elif row['syntax'] == 'oxaccess':
				kwargs[row['CLIName']] = 'premium'
			elif row['syntax'] == 'oxlanguage':
				kwargs[row['CLIName']] = lang
			elif row['syntax'] == 'oxtimezone':
				kwargs[row['CLIName']] = tz
			elif row['syntax'] == 'oxContextSelect':
				kwargs[row['CLIName']] = ucr.get('ox/context/id', '10')
			else:
				utils.fail('Unknown syntax "{}" in row:\n{}.'.format(row['syntax'], row))

	if not 'mailPrimaryAddress' in kwargs:
		kwargs['mailPrimaryAddress'] = '{}@{}'.format(uts.random_username(), mail_domain)
	kwargs['password'] = uts.random_string()

	print('*** Creating OX user with arguments:')
	ox_user_dn, ox_username = udm.create_user(**kwargs)

	try:
		client = OXHttpApi(ox_username, kwargs['password'])
	except LoginError as exc:
		utils.fail('Could not login.')

	print('\n\n*** Checking OX user:\n')

	ox_user = client.get_user()
	ox_user['anniversary'] = datetime.date.fromtimestamp(int(ox_user['anniversary']/1000.0)).strftime('%Y-%m-%d')
	ox_user['birthday'] = datetime.date.fromtimestamp(int(ox_user['birthday']/1000.0)).strftime('%Y-%m-%d')
	ox_user['oxContext'] = str(client.get_context_id())

	errors = 0
	for k, v in kwargs.items():
		if k in ['password', 'isOxUser', 'oxAccess']:
			print('Ignore: {}'.format(k))
			continue

		if ox_user[udm_to_ox[k]] == v:
			print('OK    : kwargs[%r]=%r ox_user[%r]=%r' % (k, v, udm_to_ox[k], ox_user[udm_to_ox[k]]))
		else:
			print('Error : kwargs[%r]=%r ox_user[%r]=%r' % (k, v, udm_to_ox[k], ox_user[udm_to_ox[k]]))
			errors += 1

	print('\n\n*** Checking OX contact:\n')

	contact_id = client.get_user()['contact_id']
	contact = client.contacts('get', id=contact_id, folder=GLOBAL_CONTACT_FOLDER)
	contact['anniversary'] = datetime.date.fromtimestamp(int(contact['anniversary']/1000.0)).strftime('%Y-%m-%d')
	contact['birthday'] = datetime.date.fromtimestamp(int(contact['birthday']/1000.0)).strftime('%Y-%m-%d')

	for k, v in kwargs.items():
		if k in ['password', 'isOxUser', 'oxAccess', 'oxTimeZone', 'oxLanguage', 'oxContext']:
			print('Ignore: {}'.format(k))
			continue

		if contact[udm_to_ox[k]] == v:
			print('OK    : kwargs[%r]=%r contact[%r]=%r' % (k, v, udm_to_ox[k], contact[udm_to_ox[k]]))
		else:
			print('Error : kwargs[%r]=%r contact[%r]=%r' % (k, v, udm_to_ox[k], contact[udm_to_ox[k]]))
			errors += 1

	print('\n\n*** Checking language and timezone defaults:\n')

	ox_lang = client.get('config/language')
	if ox_lang == lang:
		print('OK    : oxLanguage="{}" config/language="{}"'.format(lang, ox_lang))
	else:
		print('Error : oxLanguage="{}" config/language="{}"'.format(lang, ox_lang))
		errors += 1

	ox_tz = client.get('config/timezone')
	if ox_tz == tz:
		print('OK    : oxTimeZone="{}" config/timezone="{}"'.format(tz, ox_tz))
	else:
		print('Error : oxTimeZone="{}" config/timezone="{}"'.format(tz, ox_tz))
		errors += 1

	if errors:
		utils.fail('{} attributes were not synced correctly.'.format(errors))
