<?php #lib/90_response.php

/********************************************************************************
 *	Content: Request class                                                     *
 *	Author: Nils Otterpohl                                                      *
 *	Last modification: 03.04.2023                                               *
 *	Version: alpha (object, incomplete, uncommented, untested)                  *
 ********************************************************************************/
 
class Request
{
	private static $jwt = null;
	private static $accept = "HTML";
	private static $method = "GET";
	
	private static $route = "/";
	private static $id = null;
	private static $subroute = null;
	private static $subid = null;
	
	private static $input = [];
	private static $filter = [];
	private static $selected = [];
	private static $printID = null;
	private static $detailDepth = 0;
	
  /***** Public Static functions *****/
  
  public static function JWT() {return self::$jwt;}
  public static function Accept() {return self::$accept;}
  public static function Method() {return self::$method;}
  
  public static function Route() {return self::$route;}
  public static function ID() {return self::$id;}
  public static function Subroute() {return self::$subroute;}
  public static function SubID() {return self::$subid;}
  
  public static function Input($name) {return isset(self::$input[$name]) ? self::$input[$name] : null;}
  public static function Filter() {return self::$filter;}
  public static function Selected() {return self::$selected;}
  public static function PrintID() {return self::$printID;}
  
  public static function Read() {
  // Copied from https://stackoverflow.com/a/40582472
    $headers = null;
    if (isset($_SERVER['Authorization'])) {
      $headers = trim($_SERVER["Authorization"]);
    } else if (isset($_SERVER['HTTP_AUTHORIZATION'])) { //Nginx or fast CGI
      $headers = trim($_SERVER["HTTP_AUTHORIZATION"]);
    } elseif (function_exists('apache_request_headers')) {
      $requestHeaders = apache_request_headers();
      // Server-side fix for bug in old Android versions (a nice side-effect of this fix means we don't care about capitalization for Authorization)
      $requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
      if (isset($requestHeaders['Authorization'])) {
        $headers = trim($requestHeaders['Authorization']);
    } }
    
    // Get the access token from the header
    if (!empty($headers)) {
      if (preg_match('/Bearer\s(\S+)/', $headers, $matches)) {
        self::$jwt = $matches[1];
    } }
    // End of copied
    
    // Read accepted/requested content type
    if (isset($_SERVER["HTTP_ACCEPT"]) && "application/json"==$_SERVER["HTTP_ACCEPT"]) {
      self::$accept = "JSON";
    }
    
    // Read the requested route (resource) and method
    self::$method = $_SERVER['REQUEST_METHOD'];
    if ("HEAD"==self::$method) {
    	Response::Get()->DisableBody();
    }
    if (preg_match('$/([^/]+)/?([^/]+)?/?([^/]+)?/?([^/]+)?$', $_SERVER['PATH_INFO'] ?? "", $matches, PREG_UNMATCHED_AS_NULL)) {
      self::$route = $matches[1];
      self::$id = $matches[2];
      self::$subroute = $matches[3];
      self::$subid = $matches[4];
  } }
  
  public static function ParseInput() {
  	// Clean input
    if (isset($_SERVER["CONTENT_TYPE"]) && "application/json"==$_SERVER["CONTENT_TYPE"]) {
    	$input = self::cleanInput(json_decode(file_get_contents("php://input"), true));
    	if (!empty($input)) {
        self::$input = $input;
      }
    } else if (in_array(self::$method, ["HEAD", "GET"])) {
      self::$filter = isset($_GET["filter"]) ? self::cleanInput(json_decode($_GET["filter"], true)) : [];
      self::$selected = isset($_GET["selected"]) ? self::cleanInput(json_decode($_GET["selected"], true)) : [];
      self::$printID = isset($_GET["print"]) ? self::cleanInput($_GET["print"]) : null;
      self::$detailDepth = \Login::HasRight("ADMIN") && isset($_GET["depth"]) ? self::cleanInput($_GET["depth"]) : null;
  } }
  
  public static function VerifyInputSecToken($verifyToken) {
  	if (!empty(self::$input) && (!isset(self::$input["secToken"]) || self::$input["secToken"]!=$verifyToken)) {
  		//Response::Get()->Message("Wrong or Missing SecToken! Ignoring input.");
  		//self::$input = [];
  } }
  
  public static function IsRoot() {return "/"==self::$route;}
  public static function IsServeClient() {return self::IsRoot() && "GET"==self::$method/* && "HTML"==self::$accept*/;}
  public static function IsLogout() {return self::IsRoot() && "DELETE"==self::$method;}
  public static function IsPrint() {return "HTML"==self::$accept && !is_null(self::$printID);}
  public static function DetailDepth() {return self::$detailDepth;}
  public static function IssueNewSecToken() {return in_array(self::$method, ["POST", "PATCH", "DELETE"]);}
  public static function AllowJwtRenewal() {return "HEAD"!=self::$method && "HTML"!=self::$accept;}
  
  /***** Private Static Functions *****/
  
  private static function cleanInput($value) { // Cleans input
    if (is_null($value)) {
    	return null;
    } else if (is_array($value)) {
    	$ret = [];
      foreach ($value as $key => $element) {
        $ret[$key] = self::cleanInput($element);
    	}
    	return $ret;
    } else if (is_string($value)) {
    	return DB::Get()->escape_string($value);
    } else {
    	return intval($value);
    }
  }
}
