<?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\Oop\MethodImplementation;
	use Phast\UUID;

	class EvaluateBooleanExpressionMethodImplementation extends MethodImplementation
	{
		protected function executeInternal(Oms $oms, OmsContext $context, InstanceReference $method, ?array $parms)
		{
			$value = false;
			$returnsAttribute = $oms->getRelatedInstance($method, KnownRelationshipGuids::Evaluate_Boolean_Expression_Method__returns__Boolean_Attribute);
			$sourceInstanceRef = $oms->getRelatedInstance($method, KnownRelationshipGuids::Evaluate_Boolean_Expression_Method__has_source__Executable_returning_Work_Data);
			$booleanOperator = $oms->getRelatedInstance($method, KnownRelationshipGuids::IDR_Evaluate_Boolean_Expression_Method__uses__Boolean_Operator);
			$targetInstanceRef = $oms->getRelatedInstance($method, KnownRelationshipGuids::Evaluate_Boolean_Expression_Method__has_target__Executable_returning_Work_Data);
			
			$sourceInstance = $oms->execute($context, $sourceInstanceRef);
			if ($sourceInstance === null)
			{
				$oms->MetadataExceptions[] = new OmsMetadataException("Evaluate Boolean Expression `source instance` is null", array
				(
					"Source Instance Method Binding" => $sourceInstanceRef
				));
				// echo ("ERR: `source inst` [ from " . $sourceInstanceRef->InstanceKey . " ] null");
				return false;
			}
			if ($targetInstanceRef !== null)
			{
				$targetInstance = $oms->execute($context, $targetInstanceRef, false);

				//$this->printWorkData($context->workData);
				//echo (" @@@@ ");
				
				//echo ("source " . $sourceInstanceRef->InstanceKey . "(" . $sourceInstance->InstanceKey . ") ... operator " . $booleanOperator->InstanceKey . " ... target " . $targetInstanceRef->InstanceKey . "(" . $targetInstance->InstanceKey . ")");

				if ($booleanOperator->GlobalIdentifier == UUID::parse(KnownInstanceGuids::RelationalOperator__ExactMatch))
				{
					if ($oms->getParentClass($sourceInstance)->GlobalIdentifier->__is_equal(UUID::parse(KnownClassGuids::WorkSet)))
					{
						$sourceInstanceWorkData = $sourceInstance;
						$sourceInstance = $context->getWorkData($sourceInstance);
					}
					$value = $oms->CompareInstanceSets_ExactMatch($sourceInstance, $targetInstance);
				}
				else if ($booleanOperator->GlobalIdentifier == UUID::parse(KnownInstanceGuids::LogicalOperator__EqualTo))
				{
					if ($oms->getParentClass($sourceInstance)->GlobalIdentifier->__is_equal(UUID::parse(KnownClassGuids::WorkSet)))
					{
						$sourceInstanceWorkData = $sourceInstance;
						$sourceInstance = $context->getWorkData($sourceInstance);
					}

					$source = $context->getWorkData($sourceInstance);
					$target = $context->getWorkData($targetInstance);
					// echo ("EBE check: " . $source->Instance . " ?? " . $target);
					$value = $source === $target;
				}
			}
			else
			{
				echo ("source " . $sourceInstanceRef->InstanceKey . "(" . $sourceInstance->InstanceKey . ") ... operator " . $booleanOperator->InstanceKey . " ... target NULL!");
			}
			if ($returnsAttribute !== null)
			{
				$context->setWorkData($returnsAttribute, $value);
			}
			else
			{
				$oms->MetadataExceptions[] = new OmsMetadataException("EBE : returned null attribute", array
				(
					"Method Instance" => $method
				));
			}
			return $returnsAttribute;
		}
	}

?>