<?php
namespace App\Core\Service;
require 'vendor/autoload.php';
use Predis\Client as PredisClient;

class Redis
{
    public static  $conn = null;
    private $host = '127.0.0.1';
    private $port = 6379;
    
    private function log($message) {
        try {
            if($_ENV['LOG_PATH']) {
                if(file_exists($_ENV['LOG_PATH']. '/' . date('Y-m-d') . '.log')) {
                    error_log("\r\n".$message, 3, $_ENV['LOG_PATH']. '/' . date('Y-m-d') . '.log');
                } else {
                    error_log($message);
                }
            } else {
                error_log($message);
            }
        } catch(\Exception $e) {
            error_log($e->getMessage());
        }
    }

    public function connect()
    {
        try {
            $this->host = $_ENV['REDIS_HOST'];
            $this->port = $_ENV['REDIS_PORT'];
            
            if(self::$conn) return self::$conn;
            self::$conn = new PredisClient(['scheme' => 'tcp', 'host' => $this->host, 'port' => $this->port, 'password' => '', 'database' => 0]);
            $this->log("Redis Server connected successfully");
            return self::$conn;
        } catch(\Exception $e) {
            $this->log($e->getMessage());
        }
    }

    public function disconnect() {
        try {
            if(self::$conn) {
                self::$conn->disconnect();
            }
        } catch(\Exception $e) {
            $this->log($e->getMessage());
        }
    }

    public function setData(String $key, String $field, String $value) {
        try {
            if(!self::$conn) {
                $this->connect();
            }
            self::$conn->hset($key, $field, $value);
            return true;
        } catch(\Exception $e) {
            $this->log($e->getMessage());
            return false;
        }
    }

    public function getData(String $key, String $field) {
        try {
            if(!self::$conn) {
                $this->connect();
            }
            $data = self::$conn->hget($key, $field);
            if(!empty($data))
                return json_decode($data);
            else 
                return NULL; 
        } catch(\Exception $e) {
            $this->log($e->getMessage());
            return NULL;
        }
    }

    public function getAllData(String $key) {
        try {
            if(!self::$conn) {
                $this->connect();
            }
            $data = self::$conn->hgetall($key);
            if(!empty($data))
                return json_decode($data);
            else 
                return NULL; 
        } catch(\Exception $e) {
            $this->log($e->getMessage());
            return NULL;
        }
    }

    public function removeData(String $key, String $field) {
        try {
            if(!self::$conn) {
                $this->connect();
            }
            $data = self::$conn->hget($key, $field);
            if(!empty($data)) {
                self::$conn->hdel($key, $field);
                return true; 
            } else 
                return false; 
        } catch(\Exception $e) {
            $this->log($e->getMessage());
            return false;
        }
    }

    public function publish(String $channel, Array $data) {
        try {
            if(!self::$conn) {
                $this->connect();
            }
            $is_published = self::$conn->publish($channel, json_encode($data));
            if(!empty($is_published)) {
                $this->log($is_published);
                return true; 
            } else 
                return false; 
        } catch(\Exception $e) {
            $this->log($e->getMessage());
            return false;
        }
    }
}
