<?php
/**
 * Created by PhpStorm.
 * User: crose
 * Date: 7/9/17
 * Time: 3:14 PM
 */

namespace IMATHUZH\Qfq\Core\Store;

use IMATHUZH\Qfq\Core\Helper\OnString;
use IMATHUZH\Qfq\Core\Helper\Sanitize;

/**
 * Class Client
 * @package qfq
 */
class Client {

    /**
     * @return array|string
     * @throws \CodeException
     */
    public static function getParam() {

        // copy GET and POST and SERVER Parameter. Priority: SERVER, POST, GET
        $get = array();
        $post = array();
        $cookie = array();
        $server = array();

        // Dirty workaround to clean poisoned T3 cache
        Sanitize::digitCheckAndCleanGet(CLIENT_PAGE_TYPE);
        Sanitize::digitCheckAndCleanGet(CLIENT_PAGE_LANGUAGE);
        Sanitize::digitCheckAndCleanGet(TAB_UNIQ_ID);

        if (empty($_GET[TAB_UNIQ_ID])) {
            $_GET[TAB_UNIQ_ID] = 1; // Maybe some browser do not support 'window.name' to be misused as tabId variable: fake with '1'.
        }

        $header = self::getHeader();

        if (isset($_GET)) {
            $get = $_GET; // do not use urldecode() - http://php.net/manual/de/function.urldecode.php#refsect1-function.urldecode-notes
        }

        if (isset($_POST)) {
            $post = $_POST;
        }

        if (isset($_COOKIE[SESSION_NAME])) {
            $cookie[CLIENT_COOKIE_QFQ] = $_COOKIE[SESSION_NAME];
        }

        // In case we're behind a proxy, use the real ip as remote_address
        if (isset($_SERVER[CLIENT_HTTP_X_REAL_IP])) {
            $_SERVER[CLIENT_REMOTE_ADDRESS] = $_SERVER[CLIENT_HTTP_X_REAL_IP];
        }

        if (isset($_SERVER)) {
            $server = Sanitize::htmlentitiesArr($_SERVER); // $_SERVER values might be compromised.
        }

        // Necessary for phpUnit Tests
        if (!isset($server[CLIENT_REMOTE_ADDRESS])) {
            $server[CLIENT_REMOTE_ADDRESS] = '0.0.0.0';
        }

        // It's important to merge the SERVER array last: those entries shall overwrite client values.
        $arr = array_merge($header, $get, $post, $cookie, $server);

        return Sanitize::normalize($arr);
    }

    /**
     * Check for Header 'Authorization' and 'X-Api-Key' - no other headers will be copied here.
     * Explode the given header by '=' or ':'. Use the header name as key (purge string 'token' from example)
     * Example Header: 'Authorization: token=1234', 'Authorization: 1234', 'Authorization: token:1234'
     *
     * @return array
     */
    private static function getHeader() {

        $arr = array();

        // getallheaders() does not exist for phpunit tests
        if (!function_exists('getallheaders')) {
            return array();
        }

        $headers = getallheaders();

        foreach ([HTTP_HEADER_AUTHORIZATION, HTTP_HEADER_X_API_KEY] as $key) {
            if (isset($headers[$key])) {
                $line = $headers[$key];

                // In case the key/value is separated by ':' instead of '='
                $delimiter = (strpos($line, '=') === false) ? ':' : '=';

                // Header: 'Authorization: token=1234'
                $split = explode($delimiter, $line, 2);
                $arr[$key] = OnString::trimQuote(trim($split[1] ?? $split[0]));
            }
        }

        return $arr;
    }
}