<?php
    include_once "Reflection.php";
    include_once "RequestHeader.php";
    include_once "RequestFile.php";
    include_once "Session.php";
    class Request
    {
        use ReflectionHook;
        public static $header;
        public static $cookie;
        public static $method;
        public static $session;
        public static $contentType;
        public static $file;
        public static $url;
        public static $accepts;
        public static $ip;
        public static $isajax;
        public static $data = [];
        public static $query = [];
        public static $ready = false;
        public function __construct()
        {
            if(!Request::$ready)
            {
                Request::$header = new RequestHeader();
                Request::$cookie = new RequestCookie();
                Request::$file = new RequestFile();
                Request::$session = new Session();
                Request::$method = strtolower($_SERVER["REQUEST_METHOD"]);
                Request::$contentType = strtolower($_SERVER["CONTENT_TYPE"] ?? "");
                Request::$ready = true;
                Request::$url = $_SERVER['REQUEST_URI'];
                if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
                {
                    Request::$ip = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0];
                }else{
                    Request::$ip = $_SERVER['REMOTE_ADDR'];
                };
                
                Request::$accepts = explode(',', $_SERVER['HTTP_ACCEPT']);


                if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')
                {
                    Request::$isajax = true;
                }else{
                    if(
                        in_array("application/json", Request::$accepts) || in_array("text/json", Request::$accepts)
                    )
                    {
                        Request::$isajax = true;
                    }
                };

                $this->mutateRequest();
            }
        }
        public function getJSONRequest()
        {
            return json_decode(file_get_contents('php://input'), true);
        }
        public function mutateRequest()
        {
            if(Request::$contentType == "application/json")
            {
                Request::$data = $this->getJSONRequest();
            }
            else
            {
                if(Request::$method == "post")
                {
                    Request::$data = $_POST;
                }
                Request::$query = $_GET;
            };
        }
        public function contentType()
        {
            return Request::$contentType;
        }
        public function method()
        {
            return Request::$method;
        }
        public function get($name)
        {
            return Request::$query[$name] ?? null;
        }
        public function has($name)
        {
            return $this->input($name) !== null;
        }
        public function post($name)
        {
            return Request::$data[$name] ?? null;
        }
        public function input($name)
        {
            return Request::staticGet($name) ?? Request::staticPost($name) ?? null;
        }
        public function staticContentType()
        {
            return $this->contentType();
        }
        public function staticMethod()
        {
            return $this->method();
        }
        public function staticGet($name)
        {
            return $this->get($name);
        }
        public function staticHeaders()
        {
            return Request::$headers;
        }
        public function staticFile()
        {
            return Request::$file;
        }
        public function staticSession()
        {
            return Request::$session;
        }
        public function staticCookie()
        {
            return Request::$cookie;
        }
        public function staticPost($name)
        {
            return $this->post($name);
        }
        public function staticInput($name)
        {
            return $this->input($name);
        }
        public function staticHas($name)
        {
            return $this->has($name);
        }
        public function getAttribute($name)
        {
            return Request::staticInput($name);
        }
    };
    define("request", new Request(), false);