<?php

namespace Andweb\Yml;
use Nette;

class RestoreResolver
{
	use Nette\SmartObject;

	protected $defaults;
	protected $arr;

	public function __construct($defaults)
	{
		$this->defaults = $defaults;
	}

	public function resolveData($arr)
	{
		$this->arr = &$arr;

		// version
		$this->arr['version'] = $this->defaults['version'];

		foreach ($arr['services'] as $sectionName => &$section)
		{
			$this->restoreSection($sectionName, $section);
		}
		
		// networks section
		$this->reverseNetworks();

	}

	public function getSanitizedData()
	{
		return $this->arr;
	}

	protected function restoreSection($containerName, &$sectionArr)
	{
		$allowedKeys = [
			'image',
			'networks',
			'ports',
			'volumes',
			'labels',
			'deploy',
			'environments'
		];

		foreach ($sectionArr as $itemName => &$vals)
		{
			if (!in_array($itemName, $allowedKeys))
			{
				unset($this->arr['services'][$containerName][$itemName]);
			}

			if (method_exists($this, 'serviceRestore'.$itemName))
			{
				$this->{'serviceRestore'.$itemName}($vals);
			}
		}
		
	}



	// subservices -- auto calls see above line: 60

	public function serviceRestoreDeploy(&$deploy)
	{
		$allowedKeys = [
			'deploy' 
				=> [
					'replicas' => TRUE,
					'restart_policy' => [
						'condition' => TRUE,
						'delay'     => TRUE,
						'window'     => TRUE,
					],	
					'update_config' => [
						'parallelism' => TRUE,
						'delay'     => TRUE,
						'order'     => TRUE,
					],	
					'resources' => [
						'limits' => [
							'memory' => TRUE,
							'cpus' => TRUE,
						],
						'reservations' => [
							'memory' => TRUE,
							'cpus' => TRUE,
						],
					],	
				]
		];


		$this->arrayWalker($deploy, 0, $allowedKeys, ['deploy']);
		
	}

	public function arrayWalker(&$deploy, $level = 0, $allowedKeys, $key = [])
	{
		foreach ($deploy as $k => &$v)
		{
			if (is_array($v))
			{
				$merge = array_merge($key, [$k]);
				$this->arrayWalker($v, $level + 1, $allowedKeys, $merge);
			}
			else
			{
				$keyPart = $key;
				$keyPartK = array_merge($keyPart, [$k]);
				$inWhiteList = & Nette\Utils\Arrays::getRef($allowedKeys, $keyPartK);
				
				// DOPRDELE S TIM!, nema to tam co delat
				if (!$inWhiteList)
				{
					unset($deploy[$k]);
				}

				$inDefaults = Nette\Utils\Arrays::get($this->defaults, $keyPartK, NULL);
				if ($inDefaults)
				{
					$deploy[$k] = $inDefaults;
				}

				
	
			}
		}
	}

	public function serviceRestoreLabels(&$label)
	{
		$label = []; // reset
		$label[$this->defaults['labels']['name']] = $this->defaults['labels']['value'];
	}


	public function serviceRestorePorts(&$ports)
	{
		$allowedKeys = [
			'target',
			'published',
			'protocol',
			'mode',
		];

		$defaultSettingsKeys = [
			'mode',
		];
	
		foreach ($ports as $index => &$arr)
		{
			foreach ($arr as $k => $v)
			{
				if (!in_array($k, $allowedKeys))
					unset($arr[$k]);
				
				if (in_array($k, $defaultSettingsKeys))
					$arr[$k] = $this->defaults['ports'][$k];
			}
		}

	}

	protected function reverseNetworks()
	{
		foreach ($this->arr['networks'] as $networkSectionName => $network)
		{
			foreach ($network as $k => $v)
			{
				if ($k != 'external') 
				{
					unset($this->arr['networks'][$networkSectionName][$k]);
				}
				else
				{
					$this->arr['networks'][$networkSectionName][$k] = $this->defaults['networks']['external'];
				}
			}
	
		}
	}

}