<?php
/**
 * @controller Gateway
 */

class Gateway_Controller extends MVC_Controller
{
	public function index()
	{
		$this->header->allow();

		$request = $this->sanitize->array($_GET);

		if(!isset($request["hash"], $request["device_unique"]))
			response(500, "Invalid Request!");

		$decode = $this->hash->decode($request["hash"], system_token);

		if(!$decode)
			response(500, "Invalid Request!");
		else
			$hash = md5($decode);

		$this->cache->container("gateway.{$hash}");

		if(!$this->cache->has("devices")):
			if($this->gateway->checkUserKey($hash) > 0):
				$this->cache->set("devices", $this->gateway->getDevices($hash));
			endif;
		endif;

		if (!array_key_exists($request["device_unique"], $this->cache->get("devices")))
            response(500, "Invalid Request!");

		$this->cache->container("gateway.{$request["device_unique"]}.{$hash}");

		if(!$this->cache->exist()):
			$this->cache->setArray($this->gateway->getPending($hash, $request["device_unique"]));
		endif;

		$messages = $this->cache->getAll();

		ksort($messages);

		if(count($messages) > 0):
			$pending["automatic"] = [];
			$pending["priority"] = [];

			foreach($messages as $key => $value){
				if($value["priority"]):
					$pending["priority"][] = [
						"id" => $key,
						"sim" => $value["sim"],
						"phone" => $value["phone"],
						"message" => $value["message"]
					];
				else:
					$pending["automatic"][] = [
						"id" => $key,
						"sim" => $value["sim"],
						"phone" => $value["phone"],
						"message" => $value["message"]
					];
				endif;
			}
		else:
			$pending = [
				"automatic" => [],
				"priority" => []
			];
		endif;

		response(200, "Gateway Messages", $pending);
	}

	public function mark()
	{
		$this->header->allow();

		$request = $this->sanitize->array($_GET);

		if(!isset($request["id"], $request["hash"], $request["device_unique"]))
			response(500, "Invalid Request!");

		if(!$this->sanitize->isInt($request["id"]))
			response(500, "Invalid Request!");

		$decode = $this->hash->decode($request["hash"], system_token);

		if(!$decode)
			response(500, "Invalid Request!");
		else
			$hash = md5($decode);

		$this->cache->container("gateway.{$hash}");

		if(!$this->cache->has("devices")):
			if($this->gateway->checkUserKey($hash) > 0):
				$this->cache->set("devices", $this->gateway->getDevices($hash));
			endif;
		endif;

		if (!array_key_exists($request["device_unique"], $this->cache->get("devices")))
            response(500, "Invalid Request!");

		if($this->gateway->mark($request["id"])):
			$this->cache->container("messages.{$hash}");
			$this->cache->clear();
		endif;

		$this->cache->container("gateway.{$request["device_unique"]}.{$hash}");

		if($this->cache->has($request["id"])):
			if($this->cache->delete($request["id"])):
				response(200, "Message has been marked!");
			else:
				response(500, "Something went wrong!");
			endif;
		else:
			response(500, "Something went wrong!");
		endif;
	}

	public function received()
	{
		$this->header->allow();

		$request = $this->sanitize->array($_POST);

		if(!isset($request["hash"], $request["payload"], $request["device_unique"]))
			response(500, "Invalid Request!");

		$decode = $this->hash->decode($request["hash"], system_token);

		if(!$decode)
			response(500, "Invalid Request!");
		else
			$hash = md5($decode);

		$this->cache->container("gateway.{$hash}");

		if(!$this->cache->has("devices")):
			if($this->gateway->checkUserKey($hash) > 0):
				$this->cache->set("devices", $this->gateway->getDevices($hash));
			endif;
		endif;

		if (!array_key_exists($request["device_unique"], $this->cache->get("devices")))
            response(500, "Invalid Request!");

        if(!$this->cache->has("contacts")):
        	$this->cache->set("contacts", $this->gateway->getContacts($hash));	
        endif;

        $contacts = $this->cache->get("contacts");

        if(!$this->cache->has("webhooks")):
        	$this->cache->set("webhooks", $this->gateway->getWebhooks($hash));	
        endif;

        $webhooks = $this->cache->get("webhooks");

        if(!empty($request["payload"])):
        	$reject = [];
        	$uid = $this->gateway->getUserID($hash);

	        foreach($request["payload"] as $message):
	        	try {
				    $number = $this->phone->parse($message["address"]);
				} catch(Brick\PhoneNumber\PhoneNumberParseException $e) {
					$reject[] = $message["id"];
				}

				if (!$number->isValidNumber())
					$reject[] = $message["id"];

				if(!$number->getNumberType(Brick\PhoneNumber\PhoneNumberType::MOBILE))
					$reject[] = $message["id"];

				$message["address"] = $number->format(Brick\PhoneNumber\PhoneNumberFormat::E164);

				if(!in_array($message["id"], $reject)):
		        	if($this->gateway->checkReceived($message["id"], $uid, $request["device_unique"]) < 1):
		        		$filtered = [
		        			"rid" => $message["id"],
		        			"uid" => $uid,
		        			"did" => $request["device_unique"],
		        			"phone" => $message["address"],
		        			"message" => $message["body"],
		        			"receive_date" => date("Y-m-d g:i:s", $message["date"] / 1000)
		        		];

		        		if(!empty($webhooks)):
			        		foreach($webhooks as $webhook):
			        			if($webhook["devices"] == 0 || in_array($request["device_unique"], $webhook["devices"])):
					        		try {
										$this->guzzle->post($webhook["url"], [
							                "form_params" => [
							                	"secret" => $webhook["secret"],
							                	"name" => (isset($contacts[$message["address"]]) ? $contacts[$message["address"]]["name"] : (boolean) false),
							                	"phone" => $filtered["phone"],
							                	"message" => $filtered["message"],
							                	"receive_date" => date("m/d/Y g:i A", strtotime($filtered["receive_date"]))
							                ],
							                "timeout" => 1.50,
							                "connection_timeout" => 1.50,
							                "http_errors" => false
							            ]);
									} catch(Exception $e){
										// Ignore Exceptions
									}
								endif;
							endforeach;
						endif;

						$this->gateway->received($filtered);
		        	endif;
			    endif;
	        endforeach;

	        $this->cache->container("messages.{$hash}");
	        $this->cache->clear();
	    endif;

        response(200, "Payload Received!");
	}

	public function register()
	{
		$this->header->allow();

		$request = $this->sanitize->array($_POST);

		if(!isset($request["hash"], $request["device_unique"], $request["device_model"], $request["device_version"], $request["device_manufacturer"]))
			response(500, "Invalid Request!");

		$decode = $this->hash->decode($request["hash"], system_token);

		if(!$decode)
			response(500, "Invalid Request!");
		else
			$hash = md5($decode);

		if(!$this->sanitize->isFloat($request["device_version"]))
			response(500, "Invalid Request!");

		if($this->gateway->checkDevice($request["device_unique"], $hash) > 0):
			response(200, "Device has been registered!", [
				"hash" => $request["hash"],
				"device_unique" => $request["device_unique"]
			]);
		endif;

		if($this->gateway->checkUserKey($hash) < 1)
			response(500, "Invalid Request!");

		$uid = $this->gateway->getUserID($hash);

		$filtered = [
			"uid" => $uid,
			"did" => $request["device_unique"],
			"name" => $request["device_model"],
			"version" => $request["device_version"],
			"manufacturer" => ucfirst($request["device_manufacturer"])
		];

		if($this->gateway->register($filtered)):
			$this->cache->container("gateway.{$hash}");
        	$this->cache->clear();
			$this->cache->container("devices.{$hash}");
			$this->cache->clear();

			response(200, "Device has been registered!", [
				"hash" => $request["hash"],
				"device_unique" => $filtered["did"]
			]);
		else:
			response(500, "Something went wrong!");
		endif;
	}
}