<?php
namespace App\Service;

class Route
{
	protected $routes;

	public function __construct()
	{

	}
	public function add($type, $query, $callback)
	{
		if (is_array($type)) {
			foreach ($type as $t) {
				$this->add($t, $query, $callback);
			}
		} else {
			switch (strtoupper($type)) {
				case 'GET':
					$this->get($query, $callback);
					break;
				case 'POST':
					$this->post($query, $callback);
					break;
			}
		}
	}
	public function get($query, $callback)
	{
		if ($this->exists('get', $query)) {
			return;
		}
		$this->routes['get'][$query] = (object) ['query' => $query, 'callback' => $this->parseCallback($callback)];
	}
	public function post($query, $callback)
	{
		if ($this->exists('post', $query)) {
			return;
		}
		$this->routes['post'][$query] = (object) ['query' => $query, 'callback' => $this->parseCallback($callback)];
	}
	protected function exists($type, $query)
	{
		return isset($this->routes['post'][$query]);
	}
	protected function parseCallback($callback)
	{
		if (is_callable($callback)) {
			return $callback;
		}
		elseif (is_object($callback)) {
			return [$callback, 'index'];
		}
		elseif (is_string($callback) and strpos($callback, '@') !== false) {
			list($class, $method) = explode('@', $callback);
			$class = '\\App\\Controller\\' . $class;
			if (method_exists($class, $method)) {
				return [$class, $method];
			}
		}
		elseif (is_string($callback)) {
			$class = '\\App\\Controller\\' . $callback;
			return [$class, 'index'];
		}
	}
	public function route()
	{
		$url = $_SERVER['SCRIPT_NAME'];
		$query = $_SERVER['QUERY_STRING'];
		$method = $_SERVER['REQUEST_METHOD'];
		$route = null;
		switch (strtoupper($method)) {
			case 'GET':
				$route = $this->getGet($url, $query);
				break;
			case 'POST':
				$route = $this->getPost($url, $query);
				break;
		}
		if ($route) {
			return $this->run($route->callback);
		}
		return false;
	}
	protected function getGet($url, $query)
	{
		if (isset($this->routes['get'][$url])) {
			return $this->routes['get'][$url];
		}
		$p = get('p');
		if ($p == null) {
			$p = get('page');
			if ($p == null) {
				$p = get('m');
				if ($p == null) {
					$p = get('module');
				}
			}
		}
		if (isset($this->routes['get'][$p])) {
			return $this->routes['get'][$p];
		}
		return false;
	}
	protected function getPost($url, $query)
	{
		if (isset($this->routes['post'][$url])) {
			return $this->routes['post'][$url];
		}
		$p = get('p');
		if ($p == null) {
			$p = get('page');
			if ($p == null) {
				$p = get('m');
				if ($p == null) {
					$p = get('module');
				}
			}
		}
		if (isset($this->routes['post'][$p])) {
			return $this->routes['post'][$p];
		}
		return false;
	}
	protected function run($callback)
	{
		return call_user_func($callback);
	}
}
?>