<?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;

function url($parameters, $mergeParameters = true, $useCurrentUrl = true) {
	if (is_string($parameters)) {
		return System\Routes::url($parameters, $mergeParameters);
	}

	static $url       = null;
	static $urlParams = [];

	if ($url == null) {
		$url=parse_url($_SERVER['REQUEST_URI']);

		if (isset($url['query'])) {
			parse_str($url['query'], $urlParams);
		}
	}

	if ($mergeParameters) {
		$parameters = array_merge($urlParams, $parameters);
	}

	return  $url['path'] . '?' . urldecode(http_build_query($parameters));
}

function config($key = null, $default = null) {
	if (is_null($key)) {
		return System\Config::getInstance();
	}

	if (is_array($key)) {
		return System\Config::getInstance()->set($key);
	}

	return System\Config::getInstance()->get($key, $default);
}

function escUrl($url) {
	return $url;
}

function escAttr($attr) {
	return htmlspecialchars($attr);
}

function escHtml($url) {
	return htmlspecialchars($url);
}

function env($key, $default = null) {
	if ($env = getenv($key)) {
		return $env;
	} else {
		return $default;
	}
}

if (! function_exists('nggetext')) {
	function nggetext($text, $text2, $number) {
		return ($number > 1) ? $text2 : $text;
	}
}

function friendlyDate($date) {
	$formats = [
		1          => ['%d second ago', '%d seconds ago'],
		60         => ['%d minute ago', '%d minutes ago'],
		3600       => ['%d hour ago', '%d hours ago'],
		86400      => ['%d day ago', '%d days ago'],
		604800     => ['%d week ago', '%d weeks ago'],
		2592000    => ['%d month ago', '%d months ago'],
		31536000   => ['%d year ago', '%d years ago'],
		315360000  => ['%d decade ago', '%d decades ago'],
		3153600000 => ['%d century ago', '%d centuries ago'],
	];

	$diff     = time() - strtotime($date) + 10;
	$lastTime = 1;
	$lastText = $formats[1];

	foreach ($formats as $time => $text) {
		if ($diff < $time) {
			$units = floor($diff / $lastTime);

			return sprintf(nggetext($lastText[0], $lastText[1], $units), $units);
		}
		$lastText = $text;
		$lastTime = $time;
	}

	return $date;
}

function dotToArrayKey($key) {
	//var.key1.key2 > var['key1']['key2']
	//var.key1 > var['key1']

	return preg_replace_callback('/\.(\w+)/', function ($matches) {
		return "['" . $matches[1] . "']";
	}, $key);
}
/*
 
Vvveb\url(['module' => 'account/whishlist'])
Vvveb\url('product', ['slug' => $slug])


 function url($route, $parameters)

 
 
*/

function session($data, $default = null) {
	$session = System\Session :: getInstance();

	if (is_array($data)) {
		foreach ($data as $key => $value) {
			$session->set($key, $value);
		}
	} else {
		$value = $session->get($data);

		if ($default && ! $value) {
			return $default;
		}

		return $value;
	}
}

function filter($regex, $input, $maxInputSize = 100) {
	$matches = [];

	if (preg_match($regex, substr($input, 0, $maxInputSize), $matches)) {
		return $matches[0];
	} else {
		return false;
	}
}

function arrayAllowValues($input, $allowedValues) {
	if (! in_array($input, $allowedValues)) {
		return null;
	} else {
		return $input;
	}
}

function arrayPath(array $a, $path, $default = null) {
	$p = strtok($path, '.');

	while ($p !== false) {
		if (! isset($a[$p])) {
			return $default;
		}

		$a = $a[$p];
		$p = strtok('.');
	}

	return $a;
}

function __($text, ...$parameters) {
	return sprintf(_($text), $parameters);
}

function cssToXpath($selector) {
	//if already xpath don't transform
	//if (substr_compare($selector,'psttt_xpath', 0, 11) == 0) return substr($selector, 12, -1);

	$selector = (string) $selector;

	//convert , to | union operator to allow multiple queries
	$selector = str_replace(',', '|', $selector);

	$cssSelector = [
		// E > F: Matches any F element that is a child of an element E
		'/\s*>\s*/',
		// E + F: Matches any F element immediately preceded by an element
		'/\s*\+\s*/',
		// E F: Matches any F element that is a descendant of an E element
		'/([a-zA-Z\*="\[\]#._-])\s+([a-zA-Z\*#._-])/',
		// E:first-child: Matches element E when E is the first child of its parent
		'/(\w+):first-child/',
		// E[foo="warning"]: Matches any E element whose "foo" attribute value is exactly equal to "warning"
		'/(\w+)\[([\w\-_]+)\="([^"]*)"]/',
		// E[foo]: Matches any E element with the "foo" attribute set (whatever the value)
		'/(\w+)\[([\w_\-]+)\]/',
		// E[!foo]: Matches any E element without the "foo" attribute set
		'/(\w+)\[!([\w\-_]+)\]/',
		// [foo="warning"]: Matches any element whose "foo" attribute value is exactly equal to "warning"
		'/\[([\w\-_]+)\=\"(.*)\"\]/',

		// [foo*="warning"]: Matches any element whose "foo" attribute value contains the string "warning"
		'/\[([\w\-_]+)\*\=\"([^"]+)\"\]/',

		// [foo^="warning"]: Matches any element whose "foo" attribute value begins with the string "warning"
		'/\[([\w_\-]+)\^\=\"([^"]+)\"\]/',

		// [foo$="warning"]: Matches any element whose "foo" attribute value ends  with the string "warning"
		'/\[([\w_\-]+)\$\=\"([^"]+)\"\]/',

		// [foo]: Matches any element with the "foo" attribute set (whatever the value)
		'/\[([\w_\-]+)\]/',
		// element[foo*]: Matches any element that starts with "foo" attribute (whatever the value)
		'/(\w+)\[([\w\-]+)\*\]/',
		// [foo*]: Matches any element that starts with "foo" attribute (whatever the value)
		'/\[([\w\-]+)\*\]/',
		// div.warn*: HTML only. The same as DIV[class*="warning"]
		'/(\w+|\*)\.([\w\-_]+)\*/',
		// div.warning: HTML only. The same as DIV[class~="warning"]
		'/(\w+|\*)\.([\w\-_]+)+/',
		// .warn*: HTML only. The same as [class*="warning"]
		'/\.([\w\-\_]+)\*/',
		// .warning: HTML only. The same as [class~="warning"]
		'/\.([\w\-\_]+)+/',
		// E#myid: Matches any E element with id-attribute equal to "myid"
		'/(\w+)+\#([\w\-_]+)/',
		// #myid: Matches any E element with id-attribute equal to "myid"
		'/\#([\w\-_]+)/',
	];

	$xpathQuery = [
		'/', //element > child
		'/following-sibling::*[1]/self::', // element + precedent
		'\1//\2', //element descendent
		'\1[ 1 ]', //'*[1]/self::\1',//element:first-child
		'\1[ contains( concat( " ", @\2, " " ), concat( " ", "\3", " " ) ) ]', //element[attribute="string"]
		'\1 [ @\2 ]', //element[attribute]
		'\1 [ not(@\2) ]', //element[!attribute]
		'*[ contains( concat( " ", @\1, " " ), concat( " ", "\2", " " ) ) ]', //[foo="warning"] not implemented
		'*[ contains( concat( " ", @\1, " " ), "\2" ) ]', //[foo*="warning"]
		'*[ contains( concat( " ", @\1, " " ), concat( " ", "\2", " " ) ) ]', //[foo^="warning"] not implemented
		'*[ contains( concat( " ", @\1, " " ), concat( " ", "\2", " " ) ) ]', //[foo$="warning"] not implemented
		'//*[ @\1 ]', //[attribute]
		'\1 [ @*[starts-with(name(), "\2")] ]', //element[attr*]
		'//*[ @*[starts-with(name(), "\1")] ]', //[attr*]
		'\1[ contains( concat( " ", @class, " " ), concat( " ", "\2") ) ]', //element[class*="string"]
		'\1[ contains( concat( " ", @class, " " ), concat( " ", "\2", " " ) ) ]', //element[class~="string"]
		'*[ contains( concat( " ", @class, " " ), concat( " ", "\1") ) ]', //[class*="string"]
		'*[ contains( concat( " ", @class, " " ), concat( " ", "\1", " " ) ) ]', //element[class~="string"]
		'\1[ @id = "\2" ]', //element#id
		'*[ @id = "\1" ]', //#id
	];

	$result = (string) '//' . preg_replace($cssSelector, $xpathQuery, $selector);
	//$this->debug(STORE_CSS_XPATH_TRANSFORM, $result);
	return $result;
}
