<?php

// For backward compatibility we must check if the file exists
if ( file_exists(BASE_PATH . 'server/includes/core/class.encryptionstore.php') ) {
	require_once(BASE_PATH . 'server/includes/core/class.encryptionstore.php');
}

/**
 * PluginMDMModule Module
 */
class PluginMDMModule extends Module
{
	private $server = '';
	private $username = '';
	private $password = '';

	/**
	 * Constructor
	 * @param int $id unique id.
	 * @param array $data list of all actions.
	 */
	function PluginMDMModule($id, $data)
	{
		parent::Module($id, $data);

		$this->server = (PLUGIN_MDM_SERVER_SSL ? 'https://' : 'http://') . PLUGIN_MDM_SERVER;

		// For backward compatibility we will check if the Encryption store exists. If not,
		// we will fall back to the old way of retrieving the password from the session.
		if ( class_exists('EncryptionStore') ) {

			// Get the username and password from the Encryption store
			$encryptionStore = EncryptionStore::getInstance();
			$this->username = $encryptionStore->get('username');
			$this->password = $encryptionStore->get('password');
		} else {
			$this->username = $GLOBALS['mapisession']->getUserName();

			$this->password = $_SESSION['password']; 
			if(function_exists('openssl_decrypt')) {
				// In PHP 5.3.3 the iv parameter was added
				if(version_compare(phpversion(), "5.3.3", "<")) {
					$this->password = openssl_decrypt($this->password, "des-ede3-cbc", PASSWORD_KEY, 0);
				} else {
					$this->password = openssl_decrypt($this->password, "des-ede3-cbc", PASSWORD_KEY, 0, PASSWORD_IV);
				}
			}
		}

		$this->url = $this->server .'/Microsoft-Server-ActiveSync?Cmd=WebserviceDevice&DeviceId=webservice&DeviceType=webservice&User=' . $this->username;
	}

	/**
	 * Helper to setup a client.
	 */
	function getSoapClient()
	{
		return new SoapClient(null, array(
			'location' => $this->url,
			'uri' => $this->server,
			'trace' => 1,
			'login' => $this->username,
			'password' => $this->password
		));
	 }

	/**
	 * Function which calls the soap call to do a full resync
	 * @param int $deviceid of phone which has to be resynced
	 * @return json $response object contains the response of the soap request from Z-Push
	 */
	function resyncDevice($deviceid)
	{
		$client = $this->getSoapClient();
		return $client->ResyncDevice($deviceid);
	}

	/**
	 * Function which calls the wipeDevice soap call
	 * @param int $deviceid of phone which has to be wiped
	 * @param string $password user password
	 * @return json $response object contains the response of the soap request from Z-Push
	 */
	function wipeDevice($deviceid, $password)
	{
		if ($password == $this->password) {
			$client = $this->getSoapClient();
			return $client->WipeDevice($deviceid);
		} else {
			return false;
		}
	}

	/**
	 * function which calls the ListDeviceDetails soap call
	 * @return array $response array contains a list of devices connected to the users account
	 */
	function getDevices()
	{	
		$client = $this->getSoapClient();
		return $client->ListDevicesDetails();
	}


	/**
	  function which calls the wipeDevice soap call
	 * @param int $deviceid of phone which has to be wiped
	 * @return json $response object contains the response of the soap request from Z-Push
	 */
	function removeDevice($deviceid)
	{
		$client = $this->getSoapClient();
		return $client->RemoveDevice($deviceid);
	}
	
	/**
	 * Executes all the actions in the $data variable.
	 * @return boolean true on success of false on fialure.
	 */
	function execute()
	{
		foreach($this->data as $actionType => $actionData)
		{
			if(isset($actionType)) {
				try {
					switch($actionType)
					{
						case 'wipe':
							$this->wipeDevice($actionData['deviceid'], $actionData['password']);
							$this->addActionData('wipe', array(
								'type' => 3, 
								'wipe' => $this->wipeDevice($actionData['deviceid'], $actionData['password'])
							));
							$GLOBALS['bus']->addData($this->getResponseData());
							break;
						case 'resync':
							$this->addActionData('resync', array(
								'type' => 3, 
								'resync' => $this->resyncDevice($actionData['deviceid'])
							));
							$GLOBALS['bus']->addData($this->getResponseData());
							break;
						case 'remove':
							$this->addActionData('remove', array(
								'type' => 3, 
								'remove' => $this->removeDevice($actionData['deviceid'])
							));
							$GLOBALS['bus']->addData($this->getResponseData());
							break;
						case 'list':
							$items = array();
							$date['page'] = array();

							$rawData = $this->getDevices();
							foreach($rawData as $device){
								$device = $device->data;
								$item = array();
								$item['entryid'] = $device['deviceid'];
								$item['changed'] = $device['changed'];
								$item['deviceos'] = $device['deviceos'];
								$item['devicefriendlyname'] = $device['devicefriendlyname'];
								$item['devicetype'] = $device['devicetype'];
								$item['devicemodel'] = $device['devicemodel'];
								$item['hierarchyuuid'] = $device['hierarchyuuid'];
								$item['firstsynctime'] = $device['firstsynctime'];
								$item['lastupdatetime'] = $device['lastupdatetime'];
								$item['wipestatus'] = $device['wipestatus'];
								$item['useragent'] = $device['useragent'];
								$item['domain'] = $device['domain'];
								array_push($items, array('props' => $item));
							}
							$data['page']['start'] = 0;
							$data['page']['rowcount'] = count($rawData);
							$data['page']['totalrowcount'] = $data['page']['rowcount'];
							$data = array_merge($data, array('item' => $items));

							$this->addActionData('list', $data);
							$GLOBALS['bus']->addData($this->getResponseData());
							break;
						default:
							$this->handleUnknownActionType($actionType);
					}
				} catch (SoapFault $fault) {
					$display_message = _('Something went wrong.');
					if ($fault->faultcode === 'HTTP') {
						if ($fault->getMessage() === "Unauthorized") {
							$display_message = _('Unable to connect to Z-Push Server. Unauthorized.');
						}
						if ($fault->getMessage() === "Could not connect to host") {
							$display_message = _('Unable to connect to Z-Push Server. Could not connect to host.');
						}
						if ($fault->getMessage() === "Not Found") {
							$display_message = _('Unable to connect to Z-Push Server. Not found.');
						}
					} else if ($fault->faultcode === "ERROR") {
						$display_message = _('Device ID could not be found');
					}
					$this->sendFeedback(false, array("type" => ERROR_GENERAL, "info" => array('display_message' => $display_message)));
				}
				catch (Exception $e) {
					$this->sendFeedback(true, array("type" => ERROR_GENERAL, "info" => array('display_message' => _('Something went wrong'))));
				}
			}
		}
 	}
};
?>
