<?php
	namespace Mocha\Oop\MethodImplementations;

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

	use Phast\UUID;

	class GetReferencedInstanceSetMethodImplementation extends MethodImplementation
	{
		protected function executeInternal(Oms $oms, OmsContext $context, InstanceReference $method, ?array $parms)
		{
			$forClass = $oms->getRelatedInstance($method, KnownRelationshipGuids::Method__for__Class);
			$returnsWorkSet = $oms->getRelatedInstance($method, KnownRelationshipGuids::Get_Referenced_Instance_Set_Method__returns__Work_Set);
			$loopOnInstanceSet = $oms->getRelatedInstance($method, KnownRelationshipGuids::Get_Referenced_Instance_Set_Method__uses_reference__Executable_returning_Instance_Set);
			$targetInstance = null;

			if ($oms->is_a($loopOnInstanceSet, KnownClassGuids::MethodBinding))
			{
				$loopOnInstanceSetTarget = $oms->execute($context, $loopOnInstanceSet);
				if ($loopOnInstanceSetTarget === null)
				{
					$mx = array
					(
						"Method Instance" => $method,
						"Returns Work Set" => $returnsWorkSet,
						"Loop on Instance Set" => $loopOnInstanceSet,
						"For Class" => $forClass
					);
					
					$oms->MetadataExceptions[] = new OmsMetadataException("loop on instance set was an MB, but returned null", $mx, null, OmsMetadataExceptionSeverity::Information);
				}
				$targetInstance = $context->getWorkData($loopOnInstanceSetTarget);
			}
			else
			{
				$targetInstance = $context->getWorkData($loopOnInstanceSet);
			}

			$relationship = $oms->getRelatedInstance($method, KnownRelationshipGuids::Get_Referenced_Instance_Set_Method__uses_answer__Executable_returning_Instance_Set);
			$relhack = false;
			if (!$oms->is_a($relationship, KnownClassGuids::Relationship))
			{
				$relationship = $context->getWorkData($relationship);
				$relhack = true;
			}
			
			$mx = array
			(
				"Method Instance" => $method,
				"Returns Work Set" => $returnsWorkSet,
				"Loop on Instance Set" => $loopOnInstanceSet,
				"Get Relationship" => $relationship,
				"For Class" => $forClass,
				"Target Instance" => $targetInstance
			);
			if ($targetInstance === null)
			{
				$targetInstance = $loopOnInstanceSet;
			}

			if ($targetInstance !== null)
			{
				$singular = $oms->getAttributeValue($returnsWorkSet, KnownAttributeGuids::Singular);
				if ($singular != 1)
				{
					$singular = $oms->getAttributeValue($method, KnownAttributeGuids::Singular);
				}
				if ($singular == 1)
				{
					$value = $oms->getRelatedInstance($targetInstance, $relationship);
				}
				else
				{
					//$oms->MetadataExceptions[] = new OmsMetadataException("GRS: returning nonsingular work set", $mx, $context->CallStack, OmsMetadataExceptionSeverity::Information);
					$value = $oms->getRelatedInstances($targetInstance, $relationship);
				}
				$mx["Got Value"] = $value;
				$context->setWorkData($returnsWorkSet, $value);
				if ($relhack)
				{
					//$oms->MetadataExceptions[] = new OmsMetadataException("GRS with relhack failed", $mx, null, OmsMetadataExceptionSeverity::Information);
				}
				// $oms->MetadataExceptions[] = new OmsMetadataException("GRS call", $mx, null, OmsMetadataExceptionSeverity::Information);
			}
			else
			{
				//echo ("exec GRS for class : " . $forClass->InstanceKey);
				$oms->MetadataExceptions[] = new OmsMetadataException("GRS: target instance unspecified", $mx, $context->CallStack);
			}
			// $oms->MetadataExceptions[] = new OmsMetadataException("GRS", $mx, null, OmsMetadataExceptionSeverity::Information);
			return $returnsWorkSet;
		}
	}

?>