<?php

logger(DEBUG,"Including db_functions.php");

// to save or not to save the DB, that is the question ...
function storeDB($db, $filepath)
{
    $data = serialize($db);
    file_put_contents($filepath, $data);
 }

function loadDB(& $db, $filepath)
{
	$data = file_get_contents($filepath);
	$db = unserialize($data);
}

function mkDevicesDB($topic, $json, $group=false)
{
	global $devices, $listProperties, $listPropertiesKeys, $indexDevices, $dbInit, $logFh, $hooks;
	if (!isset($devices[$topic]))
	{
		$devices[$topic]= array();
	}
	foreach ($json as $jsonDevice)
	{
		//print_r($device);
		$fn = $jsonDevice->friendly_name;
		$fnTree = explode("/", $fn);
		$device = & $devices[$topic];
		foreach($fnTree as $fnPart)
		{
			if (!array_key_exists($fnPart, $device))
			{
				$device[$fnPart] = array();
			}
			$device = & $device[$fnPart];
		}
		if (!array_key_exists("device", $device))
		{
			$device["device"] = new device;
		}
		$device["device"]->topic = $topic;
		//$device["device"]->device = $jsonDevice;
		$device["device"]->friendlyName = $jsonDevice->friendly_name;
		if ($group)
		{
			//print_r($device);
			$device["device"]->groupID = $jsonDevice->id;
			$indexDevices[$device["device"]->groupID] = $jsonDevice->friendly_name;
		}else
		{
			addDevice($device, $fn, $jsonDevice);
		}
	}
	$dbInit += 1;
	fwrite($logFh, "################################START##################################################");
	fwrite($logFh, print_r($devices, true));
	fwrite($logFh, "################################END##################################################");

	echo "Devices DB made" . EOL;
	//print_r($devices);
}

function addDevice(& $device, $fn, $jsonDevice )
{
	global $listProperties, $listPropertiesKeys, $hooks, $indexDevices;
	$device["device"]->type = $jsonDevice->type;
	$device["device"]->ieeeAddress = $jsonDevice->ieee_address;
	if ( !empty($jsonDevice->power_source ) )
	{
		$device["device"]->powerSource = $jsonDevice->power_source;
	}
	if ($jsonDevice->definition != null)
	{
		$device["device"]->description = $jsonDevice->definition->description;
		searchPropertyKey($fn, $device["device"], $jsonDevice->definition->exposes, $listPropertiesKeys);
	}
	searchPropertyValue($fn, $device["device"], $jsonDevice, $listProperties);

	//indexing device
	$indexDevices[$device["device"]->ieeeAddress] = & $device["device"];
}

function searchPropertyKey($fn, &$device, $object, $listPropertiesKeys)
{
	foreach($listPropertiesKeys as $property)
	{
		foreach($object as $key => $value)
		{
			if (gettype($value) == "object" or gettype($value) == "array")
			{
				searchPropertyKey($fn, $device, $value, $listPropertiesKeys);
			}
			if ( isset($value->property))
			{
				$string = $value->property;
				$device->{$string}["value"] = null;
				$device->$string["functions"] = array();
			}
		}
		//print_r($device);
	}
}

function searchPropertyValue($fn, &$device, $object, $listProperties)
{
	$objectArray = (array)$object;
	foreach($listProperties as $key => $value)
	{
		if (in_array($value, $objectArray))
		{
			//echo "$value trouvé =>";
			$device->$key = $value;
			//echo $device->$key . EOL;
		}
	}
}

function changeDevice($topic, $fn, &$device, $payloadArray)
{
	//print_r($payloadArray);
	if (!empty($payloadArray))
	{
		iterateDevice($topic, $fn, $device, $device, $payloadArray);
	}else
	{
		logger(ERROR, _("payloadArray is empty!"));
	}

}

function iterateDevice($topic, $fn, $parentDevice, &$device, $payloadArray, $propertyTree="")
{
	global $changed, $mohaDB, $testMode;
	$deviceType = (gettype($device) == "object");				// = true if object
	//echo "devicetype = "; var_dump($deviceType); echo EOL;
	//print_r($payloadArray);
	//echo "device =>";print_r($device);echo EOL;
	//echo "PropertyTree ==============> " . $propertyTree . EOL;
	foreach($payloadArray as $key => $value)
	{
		$oldValue = null;
		//echo "key =>"; print_r($key); echo EOL;
		//echo "value =>"; print_r($value); echo EOL;
		//echo "type : " . gettype($value) .EOL;
		$valueType = gettype($value);
		if ( $valueType == "object")
		{
			$propertyTree .=  $key . "/";
			//echo " is Object" . EOL;
			if ($deviceType === true )
			{
				if (!property_exists($device, $key))
				{
					$device->{$key} = new stdClass;
				}
				//echo "iterating" . EOL;
				iterateDevice($topic, $fn, $parentDevice, $device->$key,  $value, $propertyTree);
			}else
			{
				//echo "is array";
				if (!array_key_exists($key, $device))
				{
					$device[$key] = new stdClass;
				}
				//echo "iterating" . EOL;
				iterateDevice($topic, $fn, $parentDevice, $device[$key], $value, $propertyTree);
			}

		}elseif ($valueType == "array")
		{
			$propertyTree .=  $key . "/";
			if ($deviceType === true )
			{
				$device->$key = array();
				iterateDevice($topic, $fn, $parentDevice, $device->$key, $value, $propertyTree);
			}else
			{
				$device[$key] = array();
				iterateDevice($topic, $fn, $parentDevice, $device[$key], $value, $propertyTree);
			}

		}else
		{
			if (empty($device->$key) or $value != null)
			{
				if (property_exists($device, $key))
				{
					if (is_array($device->$key))
					{
						$oldValue = $device->$key["value"];
					}else
					{
						$oldValue = $device->$key;
					}
				}else
				{
					$device->{$key} = array("value" => null);
					$device->$key["functions"] = array();
				}
				if ($oldValue !== $value)
				{
					$device->$key["value"] = $value;
					$changed[$fn]["key"] = $key;
					$changed[$fn]["value"] = $value;
					logger(INFO, sprintf(_("Device %s property %s, value changed to %s"), $fn, $propertyTree . $key, $value));
					if ($testMode === false)
					{
						$mohaDB->logProperty($parentDevice, $propertyTree . $key, $value,   $oldValue);
					}else
					{
						logger(INFO, _("Test mode on: not storing in DB "));
					}
				}
				if (!empty($device->$key["functions"]))
				{
					logger(DEBUG,_("executing notifications functions"));
					foreach($device->$key["functions"] as $function)
					{
						$function($device, $key, $value);
					}
				}
			}
		}
	}
}

function getDevicesValues()
{
	//TODO
}

?>