<?php

namespace GDPlayer;

class Security
{
    protected $iCache;
    protected $cipher = "AES-256-CBC";
    protected $kunciGaram = "GDPlayer";
    protected $otentikasiURL = "https://auth.gdplayer.to/";
    protected $beitKodeJS = "%s/ambil-kode-js.php?license=%s&hostname=%s";
    protected $kirimKode = "license=%s&hostname=%s";
    public function __construct()
    {
        session_write_close();
        $this->iCache = new \GDPlayer\InstanceCache();
        $this->kunciGaram .= $this->ambilKunciGaram();
    }
    public function ambilKunciGaram()
    {
        session_write_close();
        return "~F1r3b4Ll";
    }
    public function enableUAFilter()
    {
        session_write_close();
        if (isset($_SERVER["HTTP_USER_AGENT"])) {
            session_write_close();
            $cache = $this->iCache->get("ua-blocked");
            if ($cache) {
                session_write_close();
                $content = $cache;
            } else {
                session_write_close();
                open_resources_handler();
                $fp = @fopen(BASE_DIR . "includes/bin/ua-blocked.txt", "r");
                if ($fp) {
                    session_write_close();
                    stream_set_blocking($fp, false);
                    $content = stream_get_contents($fp);
                    fclose($fp);
                    $this->iCache->save("ua-blocked", $content, 2592000, "options");
                }
            }
            preg_match($content, strtolower($_SERVER["HTTP_USER_AGENT"]), $match);
            if (!empty($match)) {
                session_write_close();
                error_log("invalid UA detected => " . $_SERVER["HTTP_USER_AGENT"]);
                http_response_code(403);
                exit("Access denied!");
            }
        }
    }
    public function mekNgumbe()
    {
        session_write_close();
        $result = false;
        $hostname = parse_url(BASE_URL, PHP_URL_HOST);
        $license = get_option("gdplayer_license");
        if (empty($license) || empty($hostname)) {
            session_write_close();
            return $result;
        }
        $cache = $this->iCache->get("mekngumbeIni");
        if ($cache) {
            session_write_close();
            $data = $this->decryptURL($cache);
            if ($data) {
                session_write_close();
                $data = @json_decode($data, true);
                if (isset($data["exp"]) && isset($data["license"]) && isset($data["hostname"]) && $data["exp"] > time() && $data["license"] === $license && $data["hostname"] === $hostname) {
                    session_write_close();
                    return true;
                }
            }
        }
        //$helper = new \GDPlayer\Helper();
        //$ch = $helper->getCurlDefaultConfig(curl_init());
        //curl_setopt($ch, CURLOPT_URL, $this->otentikasiURL . "validasi.php");
        //curl_setopt($ch, CURLOPT_POST, true);
        //curl_setopt($ch, CURLOPT_POSTFIELDS, sprintf($this->kirimKode, $license, $hostname));
        //$response = curl_exec($ch);
        //$err = curl_error($ch);
        //curl_close($ch);
        //if (!$err) {
            //session_write_close();
            //$arr = @json_decode($response, true);
            //$result = is_array($arr) && isset($arr["status"]) && $arr["status"];
            $result = true;
            if ($result) {
                session_write_close();
                $data = $this->encryptURL(json_encode(["hostname" => $hostname, "license" => $license, "exp" => time() + 7200]));
                $this->iCache->save("mekngumbeIni", $data, 7200, "options");
            }
        //}
        return $result;
    }
    public function encrypt(string $plainText = '')
    {
        session_write_close();
        try {
            session_write_close();
            $ckey = "encode~" . hash("SHA256", $plainText);
            $cache = $this->iCache->get($ckey);
            if ($cache) {
                session_write_close();
                return $cache;
            } else {
                session_write_close();
                $key = base64_decode($this->kunciGaram . SECURE_SALT);
                $ivlen = openssl_cipher_iv_length($this->cipher);
                $iv = openssl_random_pseudo_bytes($ivlen);
                $ciphertextRaw = @openssl_encrypt($plainText, $this->cipher, $key, OPENSSL_RAW_DATA, $iv);
                $hmac = hash_hmac("sha256", $ciphertextRaw, $key, true);
                if (is_string($iv) && is_string($ciphertextRaw) && is_string($hmac)) {
                    session_write_close();
                    $encrypted = base64_encode($iv . $hmac . $ciphertextRaw);
                    $this->iCache->save($ckey, $encrypted, 2592000, "encode");
                    return $encrypted;
                }
            }
        } catch (\Exception $e) {
            session_write_close();
            error_log("Security encrypt => " . $e->getMessage());
        }
        return false;
    }
    public function decrypt(string $encryptedText = '')
    {
        session_write_close();
        try {
            session_write_close();
            $key = base64_decode($this->kunciGaram . SECURE_SALT);
            $c = base64_decode($encryptedText);
            $ivlen = openssl_cipher_iv_length($this->cipher);
            $iv = substr($c, 0, $ivlen);
            $hmac = substr($c, $ivlen, $sha2len = 32);
            $ciphertextRaw = substr($c, $ivlen + $sha2len);
            $originalPlaintext = @openssl_decrypt($ciphertextRaw, $this->cipher, $key, OPENSSL_RAW_DATA, $iv);
            $calcmac = hash_hmac("sha256", $ciphertextRaw, $key, true);
            if (is_string($hmac) && is_string($calcmac) && hash_equals($hmac, $calcmac)) {
                session_write_close();
                return $originalPlaintext;
            }
        } catch (\Exception $e) {
            session_write_close();
            error_log("Security decrypt => " . $e->getMessage());
        }
        return false;
    }
    public function encryptURL($url = null)
    {
        session_write_close();
        return !is_null($url) ? base64url_encode($this->encrypt($url)) : false;
    }
    public function decryptURL($url = null)
    {
        session_write_close();
        return !is_null($url) ? $this->decrypt(base64url_decode($url)) : false;
    }
    public function isSmartTv(string $ua = '')
    {
        session_write_close();
        if (empty($ua) && isset($_SERVER["HTTP_USER_AGENT"])) {
            session_write_close();
            $ua = $_SERVER["HTTP_USER_AGENT"];
        }
        $class = new \WhichBrowser\Parser($ua);
        $model = isset($class->device->model) ? strtr(strtolower($class->device->model), ["-" => '', "_" => '']) : '';
        preg_match("/seraphic|hbbtv|sraf|crkey|tpm171e|a95x-r1|netbox|mxqpro|tx3|m8s|neo-u1|t95zplus|beelink|abox|p281|hx_3229|v88|mx9|mxiii|zidoo|brightsign/i", $ua, $tv1);
        preg_match("/smart-tv|smart_tv|leelbox|minia5x|x96|mobile vr|directfb|kylo|ppc|telefunken|linux sh4|linux mips|kded|h96|x96mini|freebox|wii|playstation|nintendo|xbox|tv/i", $ua, $tv2);
        return $class->device->type === "television" || $model === "smarttv" || !empty($tv1[1]) || !empty($tv2[1]);
    }
    public function createSmartTvToken()
    {
        session_write_close();
        $result = '';
        if (isset($_SERVER["HTTP_USER_AGENT"])) {
            session_write_close();
            $class = new \WhichBrowser\Parser($_SERVER["HTTP_USER_AGENT"]);
            $result = trim($class->device->manufacturer . "~" . (isset($class->device->series) ? $class->device->series . "~" : '') . (isset($class->os->name) ? $class->os->name . "~" : '') . $class->engine->name);
        }
        return $result;
    }
    public function accessAllowed()
    {
        session_write_close();
        $referer = '';
        if (isset($_SERVER["HTTP_REFERER"])) {
            session_write_close();
            $referer = $_SERVER["HTTP_REFERER"];
        } else {
            if (isset($_SERVER["HTTP_ORIGIN"])) {
                session_write_close();
                $referer = $_SERVER["HTTP_ORIGIN"];
            } else {
            }
        }
        return is_domain_whitelisted($referer);
    }
    public function validasi()
    {
        session_write_close();
        //$helper = new \GDPlayer\Helper();
        $lb = new \GDPlayer\Model\LoadBalancers();
        $lbList = $lb->get(["link", "id"]);
        if ($lbList) {
            session_write_close();
            //$license = get_option("gdplayer_license");
            //$ch = $helper->getCurlDefaultConfig(curl_init());
            foreach ($lbList as $dt) {
                session_write_close();
                $hostname = parse_url($dt["link"], PHP_URL_HOST);
                //curl_setopt($ch, CURLOPT_URL, $this->otentikasiURL . "validasi.php");
                //curl_setopt($ch, CURLOPT_POST, true);
                //curl_setopt($ch, CURLOPT_POSTFIELDS, sprintf($this->kirimKode, $license, $hostname));
                //$response = curl_exec($ch);
                //$err = curl_error($ch);
                //if (!$err) {
                //    session_write_close();
                //    $arr = @json_decode($response, true);
                //    $allowed = is_array($arr) && isset($arr["status"]) && $arr["status"];
                //    $status = $allowed ? 1 : 0;
                    
                    $status = 1;
                    $lb->setCriteria("id", $dt["id"]);
                    $lb->update(array("status" => $status));
                //}
            }
            //curl_close($ch);
        }
    }
    public function kirimData(array $data = [])
    {
        session_write_close();
        $result = json_encode($data, true);
        return $result;
        
        $result = "{}";
        $license = get_option("gdplayer_license");
        $hostname = parse_url(BASE_URL, PHP_URL_HOST);
        $helper = new \GDPlayer\Helper();
        $ch = $helper->getCurlDefaultConfig(curl_init());
        curl_setopt($ch, CURLOPT_URL, sprintf($this->beitKodeJS, rtrim($this->otentikasiURL, "/"), $license, $hostname));
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, true));
        $response = curl_exec($ch);
        $err = curl_error($ch);
        curl_close($ch);
        if (!$err) {
            session_write_close();
            $arr = @json_decode($response, true);
            if (is_array($arr) && isset($arr["result"])) {
                session_write_close();
                $result = (string) $arr["result"];
            }
        }
        return $result;
    }
}