<?php
	namespace Mocha\Oop\MethodImplementations;

	use Mocha\Core\InstanceReference;
	use Mocha\Core\KnownAttributeGuids;
	use Mocha\Core\KnownClassGuids;
	use Mocha\Core\KnownRelationshipGuids;
	use Mocha\Core\OmsContext;
	use Mocha\Oms\Oms;
	use Mocha\Oms\OmsMetadataException;
	use Mocha\Oop\MethodImplementation;

	class ProcessRelatedUpdatesMethodImplementation extends MethodImplementation
	{

		protected function executeInternal(Oms $oms, OmsContext $context, InstanceReference $method, ?array $parms)
		{
			echo("executing PRU...");
			$classForPRU = $oms->getRelatedInstance($method, KnownRelationshipGuids::Process_Related_Updates_Method__processes_for__Class);
			if ($classForPRU === null)
			{
				$oms->MetadataExceptions[] = new OmsMetadataException("Class for PRU is empty", [
					"Process Related Updates Method" => $method
				]);
				return;
			}

			if ($classForPRU !== null)
			{
			}
			
			// //!HACK!
			// $instForPRU = $oms->getNthInstanceOf($classForPRU, 1);
			echo ("class for PRU: " . $classForPRU->InstanceKey);
			$instForPRU = $context->getWorkData($classForPRU);
			if ($instForPRU !== null)
			{
				echo("current work data for '" . $classForPRU->InstanceKey . "' = '" . $instForPRU->InstanceKey . "'");
			}
			else
			{
				echo ("inst for PRU class [" . $classForPRU->InstanceKey . "] is null");
			}

			$instExecutablesForPUMB = $oms->getRelatedInstances($method, KnownRelationshipGuids::Process_Related_Updates_Method__uses__Executable_for_PUMB);
			foreach ($instExecutablesForPUMB as $instExecutableForPUMB)
			{
				echo ("pumb exec: " . $instExecutableForPUMB->GlobalIdentifier . "<br />");
				
				if ($oms->is_a($instExecutableForPUMB, KnownClassGuids::AssignAttributeMethod))
				{
					$assignsAttribute = $oms->getRelatedInstance($instExecutableForPUMB, KnownRelationshipGuids::Assign_Attribute_Method__assigns__Attribute);
					$usesExecutableReturningAttribute = $oms->getRelatedInstance($instExecutableForPUMB, KnownRelationshipGuids::Assign_Attribute_Method__uses__Executable_returning_Attribute);

					//$context->setWorkData($assignsAttribute->GlobalIdentifier->__toString(), $usesExecutableReturningAttribute);
					echo ("for PRU inst: " . $instForPRU->InstanceKey);
					echo ("assigning attribute '" . $assignsAttribute->GlobalIdentifier . "' the value from executable '" . $usesExecutableReturningAttribute->GlobalIdentifier . "'");

					$value = $context->getWorkData($usesExecutableReturningAttribute);
					if ($value instanceof InstanceReference)
					{
						echo ("the value from work data is ##IS#'" . $value->GlobalIdentifier . "'##");
					}
					else
					{
						echo ("the value from work data is '" . $value . "'");
						$oms->setAttributeValue($instForPRU, $assignsAttribute, $value);
					}
				}
				else if ($oms->is_a($instExecutableForPUMB, KnownClassGuids::AssignRelationshipMethod))
				{
					echo ("execute method: " . $instExecutableForPUMB->GlobalIdentifier);
					$forClass = $oms->getRelatedInstance($instExecutableForPUMB, KnownRelationshipGuids::Method__for__Class);
					echo ("for class: " . $forClass->InstanceKey);

					$forClassInstance = $context->getWorkData($forClass);

					$assignsRelationship = $oms->getRelatedInstance($instExecutableForPUMB, KnownRelationshipGuids::Assign_Relationship_Method__assigns__Relationship);
					$usesExecutableReturningInstanceSet = $oms->getRelatedInstance($instExecutableForPUMB, KnownRelationshipGuids::Assign_Relationship_Method__uses__Executable_returning_Instance_Set);

					//$context->setWorkData($assignsAttribute->GlobalIdentifier->__toString(), $usesExecutableReturningAttribute);
					//echo ("assigning attribute '" . $assignsAttribute->GlobalIdentifier . "' the value from executable '" . $usesExecutableReturningAttribute->GlobalIdentifier . "'");

					echo("assigns rel: " . $assignsRelationship);
					if ($assignsRelationship instanceof InstanceReference)
					{
						$value = $context->getWorkData($usesExecutableReturningInstanceSet);
						echo ("assign val: " . $value);
						if ($value instanceof InstanceReference)
						{
							echo ("assign relationship: " . $forClassInstance->InstanceKey . " . " . $assignsRelationship->InstanceKey . " = " . $value->InstanceKey);
						}
						else
						{
							//echo( "the value from work data [" . $usesExecutableReturningInstanceSet->InstanceKey . "] is '" . $value . "'");
						}

						$singular = $oms->getAttributeValue($assignsRelationship, KnownAttributeGuids::Singular, false);
						if ($singular)
						{
							//!HACK! but this breaks multi instances in other places, so no good...
							$oms->removeRelationshipInstances($forClassInstance, $assignsRelationship);
						}
						$oms->assignRelationship($forClassInstance, $assignsRelationship, $value);
					}
				}
				else
				{
					echo ("unknown class for executable for PUMB");
				}
			}
		}
	}

?>