<?php
	namespace Mocha\Oop\MethodImplementations;

	use Mocha\Core\InstanceReference;
	use Mocha\Core\KnownAttributeGuids;
	use Mocha\Core\KnownRelationshipGuids;
	use Mocha\Core\OmsContext;
	use Mocha\Oms\Oms;
	use Mocha\Oop\MethodImplementation;
	use Phast\QuickSort;

	class BuildAttributeMethodImplementation extends MethodImplementation
	{
		protected function executeInternal(Oms $oms, OmsContext $context, InstanceReference $method, ?array $parms)
		{
			$returnsAttribute = $oms->getRelatedInstance($method, KnownRelationshipGuids::Build_Attribute_Method__returns__Attribute);
			$initialValue = $oms->getAttributeValue($method, KnownAttributeGuids::Value);
			$buildsWithAttributes = $oms->getRelatedInstances($method, KnownRelationshipGuids::Build_Attribute_Method__builds_with__Build_Attribute_Method_Component);
			
			$value = $initialValue;
			$qs = new QuickSort();
			$sortedAttributes = $qs->Sort_By($buildsWithAttributes, function($item)
			{
				$oms = mocha_get_oms();
				$order = $oms->getAttributeValue($item, KnownAttributeGuids::Order);
				return $order;
			});

			foreach ($sortedAttributes as $buildsWithAttribute)
			{
				$baExecutesMethod = $oms->getRelatedInstance($buildsWithAttribute, KnownRelationshipGuids::Build_Attribute_Method_Component__uses__Executable_returning_Attribute);
				$attr = null;
				if ($baExecutesMethod !== null)
				{
					$attr = $oms->execute($context, $baExecutesMethod);
				}
				else
				{
					$attr = $oms->execute($context, $buildsWithAttribute);
				}
				// echo ("value of `" . $attr->InstanceKey . "` is '" . $context->getWorkData($attr) . "'");
				if ($attr !== null)
				{
					$val = $context->getWorkData($attr);
					if (is_string($val))
					{
						$value .= $val;
					}
					else
					{
						if ($val !== null)
						{
							$value .= "E!". $val->InstanceKey;
						}
					}
				}
				else
				{
					echo ("ERR[" . $buildsWithAttribute->InstanceKey . "]");
					trigger_error("executeMethod did not return properly - called method: " . $buildsWithAttribute->GlobalIdentifier . " [" . $buildsWithAttribute->InstanceKey . "]");
				}
			}
			$context->setWorkData($returnsAttribute, $value);
			// echo ("value of MethodType is '" . $context->getWorkData(KnownAttributeGuids::MethodType) . "'");
			return $returnsAttribute;
		}
	}

?>