<?php

namespace DashNex\SiteManager\Model;

abstract class SMActionCaller implements Interfaces\ActionCaller {

	protected $indicators;

	public function GetIndicators($returnIds = false) {
		global $dashnex_service_manager;
		
		if($this->indicators === null) {
			$this->indicators = $dashnex_service_manager
				->getService('dashnex-indicator-manager')
				->GetIndicatorsByCaller($this, true, ! $returnIds);
		}

		return $this->indicators;
	}

	public function RefreshIndicators() {
		$this->indicators = null;
		return $this->GetIndicators();
	}

	public function GetDataArray() {
		$this->RefreshIndicators();
		$data = $this->_getDataArrayFromObject($this);
		$data['caller_type'] = $this->GetCallerType();
		$data = array_merge($data, $this->_getDataArrayFromDetails());

		return $data;
	}

	private function _getDataArrayFromObject($object) {
		$data = array();

		$reflection = new \ReflectionClass($object);
		$props = $reflection->getProperties();
		foreach($props as $prop) {
			if($prop->isStatic() || $prop->isPrivate()) {
				continue;
			}

			$prop->setAccessible(true);
			$name = $prop->getName();
			$val = $prop->getValue($object);
			if(is_array($val)) {
				$data[$name] = array();
				foreach($val as $k => $v) {
					$data[$name][$k] = $this->_getDataArrayFromObject($v);
				}
			} else if( ! is_object($val)) {
				$data[$name] = $val;
			} else if($val instanceof Interfaces\ActionCaller) {
				$data[$name] = $val->GetDataArray();
			} else {
				$data[$name] = $this->_getDataArrayFromObject($val);
			}
		}

		return $data;
	}

	private function _getDataArrayFromDetails() {
		global $dashnex_service_manager;
		
		$data = array();
		$config = $dashnex_service_manager
			->getService('dashnex-action-caller-manager')
			->GetCallerDataByType($this->GetCallerType());
		if( ! is_array($config)) {
			return $data;
		}

		if(
			! isset($config['details']) ||
			! is_array($config['details']) || 
			count($config['details']) == 0
		) {
			return $data;
		}

		foreach($config['details'] as $rowConfig) {
			if(isset($rowConfig['value']) && ! empty($rowConfig['value'])) {
				continue;
			}

			if( 
				! isset($rowConfig['property']) || 
				empty($rowConfig['property']) ||
				! preg_match('/\./', $rowConfig['property'])
			) {
				continue;
			}

			$propConfig = $rowConfig['property'];
			$propConfig = explode('.', $rowConfig['property']);
			if( ! is_array($propConfig) || count($propConfig) == 0) {
				continue;
			}

			$prop = null;
			$val = $this;
			for($i = 0; $i < count($propConfig); $i++) {
				if(
					$val === null || (
						! is_object($val) &&
						! is_array($val)
					)
				) {
					break;
				}

				$prop = $propConfig[$i];
				if(is_array($val)) {
					if( ! isset($val[$prop])) {
						$val = null;
						continue;
					}

					$val = $val[$prop];
					continue;
				}

				if(isset($val->$prop) && $val->$prop !== null) {
					$val = $val->$prop;
				} else {
					$method = 'get_' . $prop;
					if( ! method_exists($val, $method)) {
						$method = 'get' . str_replace('_', '', $prop);
					}
					if(method_exists($val, $method)) {
						$val = $val->$method();
					} else {
						$val = null;
					}
				}
			}

			$dataVar = &$data;
			for($i = 0; $i < count($propConfig); $i++) {
				if($i < count($propConfig) - 1) {
					$dataVar[$propConfig[$i]] = array();
					$dataVar = &$dataVar[$propConfig[$i]];
				} else {
					$dataVar[$propConfig[$i]] = $val;
				}
			}
		}

		return $data;
	}

}