<?php

/**
 * Vvveb
 *
 * Copyright (C) 2020  Ziadin Givan
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

namespace Vvveb\System;

define('COMPONENT_OPTION_NUMERIC', 0);
define('COMPONENT_OPTION_STRING', 1);
define('COMPONENT_OPTION_LIST', 2);
define('COMPONENT_OPTION_BOOL', 3);
define('COMPONENT_OPTION_PRODUCT_ID', 4);
define('COMPONENT_OPTION_CATEGORY_ID', 5);

//define('COMPONENT_CACHE_EXPIRE', 360);
class Component {
	public $cacheKey;

	public $cacheExpire = 30; //seconds

	function __construct($options) {
		$request = Request :: getInstance();

		if (isset(static :: $defaultOptions)) {
			$this->options = $this->filter($options);
		}

		foreach ($this->options as $key => &$value) {
			if (is_array($value)) {
				foreach ($value as $val) {
					if ($val == 'url') {
						if (isset($request->get[$key])) {
							$value = $request->get[$key];

							break;
						} else {
							$value = $value[1];
						}
					}
				}
			}

			if ($value === 'url') {
				$value = isset($request->get[$key]) ? $request->get[$key] : null;
			}
		}

		static :: $defaultOptions = array_merge(['language_id' => 1, 'store_id' => 1], static :: $defaultOptions);

		$this->request = Request::getInstance();
		$this->view    = View::getInstance();
		$this->session = Session::getInstance();
	}

	function invalidateCache() {
	}

	function cacheKey() {
		if (isset($this->cacheKey)) {
			return $this->cacheKey;
		}
		$this->cacheKey = md5(serialize($this->options));

		return $this->cacheKey;
		//build cache key
		//change to md5 if collisions are detected but unlikely
//		$hash = sprintf("%u",md5(serialize($this->options)));
		$hash = '';

		if (isset($this->_hash)) {
			$hash = $this->_hash;
		}

		return $this->cacheKey = get_class($this) . '_' . ID_HOST . '_' . $hash;
	}

	function filter(&$options) {
		//remove fields not declared in the class
		if (is_array($options)) {
			if (isset($options['_hash'])) {
				$this->_hash = $options['_hash'];
				unset($options['_hash']);
			}
			//$intersect = array_intersect_key($options, static :: $defaultOptions);
			//$diff = array_diff_key(static :: $defaultOptions, $options);
			//return $options = $intersect + $diff;
			//var_dump($intersect + $diff);
			return array_merge(static :: $defaultOptions, $options);
		} else {
			return static :: $defaultOptions;
		}

		return $options;
	}

	function results() {
		//check cache
		$memcache = Cache :: getInstance();
		//return false;
		return $memcache->get($this->cacheKey);
	}

	function generateCache($results) {
		$cache  = Cache :: getInstance();
		$expire = $_SERVER['REQUEST_TIME'] + $this->cacheExpire;

		if (! $results) {
			$results = 0;
		}
		$memcache->set($this->cacheKey, $results, $expire + COMPONENT_CACHE_EXPIRE);

		return $memcache->set('expire_' . $this->cacheKey, $expire, $expire + COMPONENT_CACHE_EXPIRE);
	}
}
