#!/usr/bin/env python

import os
import sys
import json
import time
import base64
import urllib2


class MethodRequest(urllib2.Request):
	def __init__(self, *args, **kwargs):
		try:
			self._method = kwargs.pop('method')
		except KeyError:
			self._method = None
		return urllib2.Request.__init__(self, *args, **kwargs)

	def get_method(self, *args, **kwargs):
		if self._method is not None:
			return self._method
		return urllib2.Request.get_method(self, *args, **kwargs)


def _get_credentials():
	return 'admin', os.environ.get('SYSTEM_ADMIN_PASSWORD', 'admin123')


def _access_gofer(method, url, data):
	username, password = _get_credentials()
	creds = base64.b64encode('%s:%s' % (username, password))
	headers = {
		'Content-Type': 'application/json',
		'Accept': 'application/json',
		'Authorization': 'Basic %s' % creds
		}
	if data:
		data = json.dumps(data)
	request = MethodRequest(url, data, headers, method=method)
	print '%sing %s' % (method, url)
	return urllib2.urlopen(request)


def get(component, url, data=None):
	url = 'http://localhost:8080/gofer/%s/rest/%s' % (component, url)
	return _access_gofer('GET', url, data)


def put(component, url, data=None):
	url = 'http://localhost:8080/gofer/%s/rest/%s' % (component, url)
	return _access_gofer('PUT', url, data)


def list_objects(component, obj_name):
	return json.loads(get(component, '%s/' % obj_name).read())['items']


def find_ldap_configuration():
	for obj in list_objects('configurationAdminManager', 'configurations'):
		if obj.get('factoryPid') == 'com.mwaysolutions.relution.platform.security.ldap' and obj.get('pid'):
			return obj


def create_or_update_ldap_configuration():
	host_dn = os.environ.get('LDAP_HOSTDN')
	ldap_password = open('/etc/machine.secret').read()
	obj = find_ldap_configuration()
	if not obj:
		sys.exit(1)
	property_map = obj['propertyMap'].copy()
	property_map.update({
		'.ldap.password': {'className': 'java.lang.String',
			'value': ldap_password},
		'ldap.userDn': {'className': 'java.lang.String',
			'value': host_dn}})

	orga_unique_name = os.environ.get('ORGA_NAME')
	synthetic_group_name = property_map['group.syntheticGroup']['value']
	property_map.update({
		'groupRoles.' + orga_unique_name.upper() + ' ' + synthetic_group_name: {
			'className': '[Ljava.lang.String;',
			'value': [
				'%o AppStore User',
				'%o Device User'
			]
		}
	})

	data = {
		'factoryPid': 'com.mwaysolutions.relution.platform.security.ldap',
		'pid': obj['pid'],
		'propertyMap': property_map,
		'version': obj['version'] + 1,
		}
	put('configurationAdminManager', 'configurations/%s' % obj['pid'], data)


if __name__ == '__main__':
	if len(sys.argv) > 2 and sys.argv[1] != 'install':
		sys.exit(0)
	i = 0
	print 'Waiting for Relution to start (max 10 minutes)'
	while i < 200:
		request = MethodRequest('http://localhost:8080/relution/portal/#/login')
		try:
			if find_ldap_configuration() is None:
				raise RuntimeError("Not yet configured...")
		except:
			i += 1
			time.sleep(3)
			print '.',
			sys.stdout.flush()
		else:
			print
			break
	else:
		print 'Relution did not respond in time! Stopping here'
		sys.exit(2)
	print 'Relution responds... configuring...'
	create_or_update_ldap_configuration()
