<?php

	namespace Mocha\Core;

	class OmsContext
	{
		private $elementParms;
		public $workData;
		private $temporaryData;

		public $CallStack;

		public function __construct()
		{
			$this->elementParms = array();
			$this->workData = array();
			$this->temporaryData = array();
			$this->CallStack = array();
		}

		public function setElementParm(InstanceReference $elementContent, string $parmId, $value)
		{
			if (!array_key_exists($elementContent->DatabaseId, $this->elementParms))
			{
				$this->elementParms[$elementContent->DatabaseId] = array();
			}
			$this->elementParms[$elementContent->DatabaseId][$parmId] = $value;
		}

		public function getElementParm(InstanceReference $elementContent, string $parmId, $defaultValue = null)
		{
			if (array_key_exists($elementContent->DatabaseId, $this->elementParms))
			{
				if (array_key_exists($parmId, $this->elementParms[$elementContent->DatabaseId]))
				{
					return $this->elementParms[$elementContent->DatabaseId][$parmId];
				}
			}
			return $defaultValue;
		}
		public function setWorkData(InstanceReference|string|InstanceKey|array $parm, $value)
		{
			/**
			 * @var \Mocha\Oms\MySQLDatabaseOms
			 */
			$oms = mocha_get_oms();

			// "Work Data" are .. "smart" variables
			// They can be restricted to a set of "valid classes" (via `Work Data.has valid Class`)
			// They could potentially also do a whole bunch of other validations if we want them to

			$parm = $oms->normalizeInstanceReference($parm);
			$key = $parm->GlobalIdentifier->__toString();

			// When setting a Work Data, first check to make sure the passed-in value is appropriate
			// for the given Work Data. If the Work Data is a Work Set, check to make sure the value
			// is indeed an InstanceReference, and that its parent class is in the selection list of
			// `Work Set.has valid Class` for the given Work Set.
			
			$expectedDataType = "";
			$actualDataType = "";
			if (!$oms->validateWorkDataType($parm, $value, $expectedDataType, $actualDataType))
			{
				$printBacktrace = false;
				trigger_error("invalid work data (expected: " . $expectedDataType . ", got: " . $actualDataType . " [ " . $value . " ] " . ") for attribute " . $parm->InstanceKey . " @ " . $parm->GlobalIdentifier);
				if ($printBacktrace)
				{
					debug_print_backtrace();
				}
			}

			// Now here's where we start fudging things... If the Work Data is a Work Set, and the
			// value is a Class, AND the Work Set valid classes DOES NOT include `Class`, THEN we
			// should *evaluate* the Class value *as a work set* and see if THAT value is of a class
			// valid for the Work Set. This should only happen once. If we are satisfied, assign THAT
			// value to the given Work Set and we're all good.
			if ($oms->is_a($parm, KnownClassGuids::WorkSet))
			{
				$Valid_Classes_for_Work_Set = $oms->getRelatedInstances($parm, KnownRelationshipGuids::Work_Set__has_valid__Class);
				if ($oms->is_a($value, KnownClassGuids::Clasz))
				{
					if (!$oms->instanceSetContains($Valid_Classes_for_Work_Set, KnownClassGuids::Clasz))
					{
						$Evaluated_Value_for_Class = $this->getWorkData($value);
						if ($Evaluated_Value_for_Class !== null)
						{
							$pclass = $oms->getParentClass($Evaluated_Value_for_Class);
							
							if ($oms->instanceSetContains($Valid_Classes_for_Work_Set, $pclass))
							{
								$value = $Evaluated_Value_for_Class;
								echo ("Work Set evaluated for class OK");
							}
							else
							{
								echo ("Evaluated value for Class not valid for Work Set ");
							}
						}
						else
						{
							// echo ("Evaluated value for Class was null! ");
						}
					}
					else
					{
						echo ("Valid Classes for Work Set contains Class");
					}
				}
			}
			
			$this->workData[$key] = $value;
		}
		public function getWorkData(InstanceReference|string|InstanceKey|array $parmId, $defaultValue = null)
		{
			/**
			 * @var \Mocha\Oms\MySQLDatabaseOms
			 */
			$oms = mocha_get_oms();

			$parmId = $oms->normalizeInstanceReference($parmId);
			$key = $parmId->GlobalIdentifier->__toString();
			
			if (array_key_exists($key, $this->workData))
			{
				return $this->workData[$key];
			}
			return $defaultValue;
		}


		public function setTemporaryVariable(InstanceReference $key, $value)
		{
			$key = $key->GlobalIdentifier->__toStringFormat(false, "", "");
			$this->temporaryData[$key] = $value;
		}
		public function getTemporaryVariable(string|InstanceReference $key, $defaultValue = null)
		{
			$key = $key->GlobalIdentifier->__toStringFormat(false, "", "");
			if (array_key_exists($key, $this->temporaryData))
			{
				return $this->temporaryData[$key];
			}
			return $defaultValue;
		}

	}

?>