<?php

class Atmail_Ldap
{
	// static helper functions
	public static $ldapOptionsMapping = array(
			'ldap_host' => 'host',
			'ldap_basedn' => 'baseDn',
			'ldap_bindauthdn' => 'bindAuthDn',
			'ldapType' => 'ldapType',
			'ldap_useSsl' => 'useSsl'
	    );
	const LDAP_TYPE_OPENLDAP = 'openldap';
	const LDAP_TYPE_ACTIVEDIRECTORY = 'activedirectory';
		
	public $account = '';
	public $config = array();
	public $_ldapOptions = array();
	public $ldapType = self::LDAP_TYPE_OPENLDAP;
	public $username = '';
	public $domain = '';
	public $domainDC = '';
	public $bindAuthDn = '';
	
	
	
	public function __construct( $account, $config )
	{
		$this->account = $account;
		$this->config = $config;
		$this->_ldapOptions = $this->processConfig();
	}

	public function ldapFilterString( $string )
	{
		/*
			supported variables :
			
		    %u = user@domain.com 
		    %n = user 
		    %d = domain.com 
		    %D = dc=domain,dc=com
		*/

		return str_replace('%D', $this->domainDC, str_replace('%d', $this->domain, str_replace('%n', $this->username, str_replace('%u', $this->account, $string))));
	}
	
	public function processConfig()
	{
		list($this->username, $this->domain) = explode('@', $this->account);
		$domainComponents = explode('.', $this->domain);
		foreach($domainComponents as $domainComponent)
		{
			$this->domainDC .= 'DC=' . $domainComponent . ',';
		}
		$this->domainDC = trim($this->domainDC, ',');
		
		$_buildLdapOptions = array();
		foreach($this->config as $configKey => $configValue)
		{
			if(array_key_exists($configKey, self::$ldapOptionsMapping))
			{
				$_buildLdapOptions[self::$ldapOptionsMapping[$configKey]] = $configValue;
			}
			else if(in_array($configKey, self::$ldapOptionsMapping))
			{
				$_buildLdapOptions[$configKey] = $configValue;
			}
		}
		$this->ldapType = $_buildLdapOptions['ldapType'];
		unset($_buildLdapOptions['ldapType']);
	
			// setup ldap options
		$_buildLdapOptions['bindRequiresDn'] = ($this->ldapType == self::LDAP_TYPE_OPENLDAP);
		$_buildLdapOptions['accountCanonicalForm'] = 4;

		// If using AD, change this to the domain
		if($this->config['ldapType'] == 'activedirectory' && $this->config['ldap_bindauthdn'] == '%u') {
			$_buildLdapOptions['accountDomainName'] = $this->domain;
		} else {
			$_buildLdapOptions['accountDomainName'] = '';			
		}

		$_buildLdapOptions['accountDomainNameShort'] = '';

		$baseDnParts = explode('dc=', strtolower($_buildLdapOptions['baseDn']));
		foreach($baseDnParts as $baseDnPart)
		{
			if($baseDnPart == '') continue;
			$baseDnPart = trim($baseDnPart, ',');
			if($_buildLdapOptions['accountDomainNameShort'] == '')
			{
				$_buildLdapOptions['accountDomainNameShort'] = strtoupper($baseDnPart);
			}
			$_buildLdapOptions['accountDomainName'] .= $baseDnPart . ".";
		}
		$_buildLdapOptions['accountDomainName'] = trim($_buildLdapOptions['accountDomainName'], '.');
		$this->bindAuthDn = $this->ldapFilterString($_buildLdapOptions['bindAuthDn']);
		unset($_buildLdapOptions['bindAuthDn']);
		
		return $_buildLdapOptions;
	}

	// returns a ldapOptions array for use in Zend_Ldap
	// $config is expected to be section='dovecot' from Config table
	public function ldapOptions()
	{
		return $this->_ldapOptions;
	}
	
	public function ldapCurrentRootDetails( )
	{
		if(isset($this->config['ldap_rootdn']))
		{
			return array(
				'username' => $this->ldapFilterString($this->config['ldap_rootdn']), 
				'password' => $this->config['ldap_rootpw']
			);
		}
		return null;
	}

}