<?php
/*
 * Copyright (c) 2013, webvariants GbR, http://www.webvariants.de
 *
 * This file is released under the terms of the MIT license. You can find the
 * complete text in the attached LICENSE file or online at:
 *
 * http://www.opensource.org/licenses/mit-license.php
 */

class WV8_Service extends WV_Service_Property {
	public function loadFromArray(array $data, array $oldData = null) {
		$cache  = sly_Core::cache();
		$struct = $cache->get('globalsettings', 'settings', null);

		if ($struct === null || $data !== $oldData) {
			$settings = parent::loadFromArray($data, $oldData);
			$struct   = array();

			foreach ($settings as $setting) {
				$namespace = $setting->getNamespace();
				$name      = $setting->getName();

				$struct[$namespace][$name] = $setting;
			}

			sly_Core::cache();
			$cache->set('globalsettings', 'settings', $struct);
		}

		return $struct;
	}

	protected function onNew(WV_Property $property) {
		$pagename = $property->getPagename();

		if (empty($pagename)) {
			throw new WV8_Exception('Der Seitenname darf nicht leer sein.');
		}

		if ($property->isLocal()) {
			$this->addToConfig($property);
		}
		else {
			$this->addToDatabase($property);
		}

		WV8_Settings::clearCache();
	}

	protected function onDeleted(WV_Property $property) {
		if ($property->isLocal()) {
			$this->removeFromConfig($property);
		}
		else {
			$this->removeFromDatabase($property);
		}

		WV8_Settings::clearCache();
	}

	protected function onChangedDatatype(WV_Property $oldVersion, WV_Property $newVersion) {
		if ($oldVersion->isLocal()) {
			$this->addToConfig($oldVersion);
		}
		else {
			$sql       = WV_SQL::getInstance();
			$name      = $oldVersion->getName();
			$namespace = $oldVersion->getNamespace();

			$sql->query('UPDATE ~wv8_values SET `values` = ? WHERE `namespace` = ? AND `name` = ?', array('', $namespace, $name), '~');
		}

		WV8_Settings::clearCache();
	}

	protected function onChangedParameters(WV_Property $oldVersion, WV_Property $newVersion) {
		$this->onChangedDatatype($oldVersion, $newVersion);
	}

	protected function onChanged(WV_Property $oldVersion, WV_Property $newVersion) {
		if ($oldVersion->isLocal() !== $newVersion->isLocal()) {
			if ($oldVersion->isLocal()) {
				$this->removeFromConfig($oldVersion);
				$this->addToDatabase($newVersion);
			}
			else {
				$this->removeFromDatabase($oldVersion);
				$this->addToConfig($newVersion);
			}
		}

		WV8_Settings::clearCache();
	}

	protected function createProperty($name, array $property) {
		return new _WV8_Setting($name, $property);
	}

	private function removeFromConfig(_WV8_Setting $setting) {
		$name      = $setting->getName();
		$namespace = $setting->getNamespace();
		$config    = sly_Core::config();
		$key       = $namespace.'.'.$name;

		$config->remove('global_settings_values/'.$key);
	}

	private function removeFromDatabase(_WV8_Setting $setting) {
		$name      = $setting->getName();
		$namespace = $setting->getNamespace();
		$sql       = WV_SQL::getInstance();

		$sql->query('DELETE FROM ~wv8_values WHERE `namespace` = ? AND `name` = ?', array($namespace, $name), '~');
	}

	private function addToConfig(_WV8_Setting $setting) {
		$name      = $setting->getName();
		$namespace = $setting->getNamespace();
		$config    = sly_Core::config();
		$key       = 'global_settings_values/'.$namespace.'.'.$name;

		$oldValue = $config->get($key, '');
		$config->setLocal($key, WV8_Settings::fixValues($oldValue));
	}

	private function addToDatabase(_WV8_Setting $setting) {
		$name      = $setting->getName();
		$namespace = $setting->getNamespace();
		$sql       = WV_SQL::getInstance();
		$values    = WV8_Settings::encodeValues(WV8_Settings::fixValues($setting->getDefault()));

		$sql->query('INSERT IGNORE INTO ~wv8_values (`namespace`,`name`,`values`) VALUES (?,?,?)', array($namespace, $name, $values), '~');
	}

	public function store(_WV8_Setting $setting, $values) {
		$name      = $setting->getName();
		$namespace = $setting->getNamespace();

		// store data in storage
		if ($setting->isLocal()) {
			$config = sly_Core::config();
			$key    = $namespace.'.'.$name;

			$config->remove('global_settings_values/'.$key);
			$config->setLocal('global_settings_values/'.$key, $values);
		}
		else {
			$encoded = WV8_Settings::encodeValues($values);
			$sql     = WV_SQL::getInstance();

			$sql->query('UPDATE ~wv8_values SET `values` = ? WHERE `namespace` = ? AND `name` = ?', array($encoded, $namespace, $name), '~');
		}

		// store the new data in cache
		$cache   = sly_Core::cache();
		$ns      = 'globalsettings.values';
		$key     = sly_Cache::generateKey($namespace, $name);
		$setting = array('params' => $setting->getParams(), 'datatype' => $setting->getDatatype(), 'raw' => $values);

		$cache->set($ns, $key, $setting);
	}

	public function rebuild(array $settings) {
		$sql = WV_SQL::getInstance();
		$sql->beginTransaction();

		foreach ($settings as $namespace => $list) {
			foreach ($list as $name => $setting) {
				$this->onNew($setting);
			}
		}

		$sql->commit();
	}
}
