<?php

namespace App\Filters;

use App\DAO\AuthDAO;
use App\Services\JWTService;
use App\Utils\SystemGateways;
use CodeIgniter\API\ResponseTrait;
use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Config\Services;

class JWTAuthenticationFilter implements FilterInterface {
	use ResponseTrait;

	public function before(RequestInterface $request, $arguments = null) {

		$authDao = new AuthDAO();
		$uri_request = preg_replace( '/\?.*$/', '', $_SERVER ['REQUEST_URI'] );
		$uri_request = str_replace( "/v1/public/", "/", $uri_request );
		$uri_request = str_replace( "/caesegatos_dev/public/", "/", $uri_request );
		$uri_request = str_replace( "/caesegatos_feature/public/", "/", $uri_request );
		$uri_request = str_replace( "/caesegatos_release/public/", "/", $uri_request );
		$uri_request = str_replace( "/public/", "/", $uri_request );
		$routes = SystemGateways::routes;
		for($i = 0, $route = [ ], $len = count( $routes ); $i < $len; $i++) {
			$url_regex = '/^\/' . str_replace( '/', '\/', $routes [$i] ['url'] ) . '$/';
			if ($routes [$i] ['method'] === $_SERVER ['REQUEST_METHOD'] && preg_match( $url_regex, $uri_request )) {
				$route = $routes [$i];
				break;
			}
		}
		$endpointId = $route ? $authDao->getEndpointIdByControllerAndActionCombined( $route ['action'] ) : 0;
		log_message( 'info', $this->logMessage( $uri_request, $route, $endpointId ) );
		if (!$endpointId) {
			log_message( 'error',
				"The route $uri_request has no corresponding record on database endpoints table or this user has no permission for this route. In order to fix it, register the endpoint on database manually on first case or conceive the correct permission on second case." );
			return Services::response()->setJSON( [ 
				'message' => 'Acesso não autorizado.'
			] )
				->setStatusCode( ResponseInterface::HTTP_UNAUTHORIZED );
		}
		$authenticationHeader = $request->getServer( 'HTTP_AUTHORIZATION' );
		$route ['endpoint_id'] = $endpointId;
		$token_is_valid = (new JWTService())->validateJWTFromRequest( $authenticationHeader, $route );
		if ($token_is_valid) {
			return $request;
		} else {
			return Services::response()->setJSON( [ 
				'message' => 'Acesso não autorizado.'
			] )
				->setStatusCode( ResponseInterface::HTTP_UNAUTHORIZED );
		}

	}

	private function logMessage(string $uri_request, array $route, int $endpointId): string {

		$json = json_encode( $route );
		if (!$route) {
			return "The system received a request on url $uri_request. No corresponding route was found.";
		}
		return "The system received a request on url $uri_request. The route found was $json and endpoint_id = $endpointId";

	}

	public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) {


	}

}
