<?php

/**
 * Created by PhpStorm.
 * User: Kavand
 * Date: 10/6/2018
 * Time: 3:49 PM
 */
class DAL
{

    protected $link;
    protected $mysqli;

    protected $ServerName;
    protected $DBName;
    protected $User;
    protected $Pass;

    protected $error = "";

    // public function __construct($config)
    // {
    //     require_once($config);

    //     $this->ServerName = DB_SERVER;
    //     $this->DBName = DB_NAME;
    //     $this->User = DB_USER;
    //     $this->Pass = DB_PASS;
    //     return $this;
    // }


    public function DAL($config)
    {
        require_once($config);
        $this->ServerName = DB_SERVER;
        $this->DBName = DB_NAME;
        $this->User = DB_USER;
        $this->Pass = DB_PASS;
        return $this;
    }

    public function error()
    {
        $e = $this->error . "";
        $this->error = "";
        return $e;
    }

    protected function Connect()
    {
        $this->link = mysqli_connect($this->ServerName, $this->User, $this->Pass, $this->DBName);
        $this->mysqli = new mysqli($this->ServerName, $this->User, $this->Pass, $this->DBName);
        $this->mysqli->set_charset('utf8');
        mysqli_set_charset($this->link, "utf8");
        mysqli_select_db($this->link, $this->DBName);
        return $this->mysqli;
    }

    public function Select($SelectSql)
    {
//        mysqli_fetch_assoc
        $this->Connect();
        $result = null;
        mysqli_set_charset($this->link, "utf8");
        $result = mysqli_query($this->link, $SelectSql);
        mysqli_set_charset($this->link, "utf8");
        $this->DisConnect();
        try {
            if (!empty($result)) {
                $template = array();
                $return = array();
                $finfo = $result->fetch_fields();
                foreach ($finfo as $val):
                    $template[] = $val->name;
                endforeach;
                while ($row = mysqli_fetch_assoc($result)):
                    $return[] = array();
                    $index = count($return) - 1;
                    for ($i = 0; $i < count($template); $i += 1):
                        $return[$index][$template[$i]] = $row[$template[$i]];
                    endfor;
                endwhile;
                $result->free();

                if ((isset($return)) AND (!empty($return)) AND (count($return) > 0)) {
                    return $return;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } catch (Exception $e) {
            return false;
        }
    }

    public function DoCommand($sql)
    {
        $this->Connect();
        if (mysqli_query($this->link, $sql)) {
            $this->DisConnect();
            return true;
        } else {
            $this->DisConnect();
            return false;
        }
    }

    public function DoCommandID($sql)
    {
        $this->Connect();
        if (mysqli_query($this->link, $sql)) {
            $id = mysqli_insert_id($this->link);
            $this->DisConnect();
            return $id;
        } else {
            $this->DisConnect();
            return false;
        }
    }

    public function Connection($comment)
    {

        if ($comment == "open")
            $result = $this->Connect();
        if ($comment == 'close')
            $result = $this->DisConnect();
        return $result;
    }

    protected function DisConnect()
    {
        if (mysqli_close($this->link)) {
            return true;
        } else {
            return false;
        }
    }

    protected function setStatement($query, $param)
    {
        $stmt = $this->mysqli->prepare($query);
        $ref = new ReflectionClass('mysqli_stmt');
        try {
            if (count($param) != 0) {
                $refArr = array();
                foreach ($param as $k => $v) $refArr[] = &$param[$k];
                $method = $ref->getMethod('bind_param');
                $method->invokeArgs($stmt, $refArr);
            }
        } catch (Exception $e) {
            $this->error = $e;
            if ($stmt != null) {
                $stmt->close();
            }
        }
        return $stmt;
    }


    protected function Params($param)
    {
        $params = array();
        if (count($param) > 0):
            $params=array('',);
            foreach ($param as $p) :
                $key = key($p);
                $params[0] .= $key;
                $params[] = $p[$key];
            endforeach;
        endif;
        return $params;
    }

    public function cSelect($query, ...$param)
    {
        try {
            $params = $this->Params($param);
            $this->Connect();
            $result = null;
            mysqli_set_charset($this->mysqli, "utf8");
            $builder = $this->setStatement($query, $params);
            mysqli_set_charset($this->mysqli, "utf8");
            $this->DisConnect();
            //$execute
            $execute = $builder->execute();
            if ($execute):
                $result = $builder->get_result();
                if (!empty($result)) :
                    $template = array();
                    $return = array();
                    $finfo = $result->fetch_fields();
                    foreach ($finfo as $val):
                        $template[] = $val->name;
                    endforeach;
                    while ($row = $result->fetch_assoc()):
                        $return[] = array();
                        $index = count($return) - 1;
                        for ($i = 0; $i < count($template); $i += 1):
                            $return[$index][$template[$i]] = $row[$template[$i]];
                        endfor;
                    endwhile;
                    $result->free();
                    $builder->close();
                    if ((isset($return)) AND (!empty($return)) AND (count($return) > 0)) :
                        return $return;
                    else :
                        return false;
                    endif;
                else :
                    return false;
                endif;
            else :
                return false;
            endif;
        } catch (Exception $e) {
            return false;
        }
    }

    public function cDoCommand($sql, ...$param)
    {
        $params = $this->Params($param);
        $this->Connect();
        $builder = $this->setStatement($sql, $params);
        $status = $builder->execute();
        if ($status OR $builder->affected_rows > 0) {
            $builder->close();
            $this->DisConnect();
            return true;
        } else {
            $this->error = $builder->error;
            $builder->close();
            $this->DisConnect();
            return false;
        }
    }

    public function cDoCommandID($sql, ...$param)
    {
        $params = $this->Params($param);
        $this->Connect();
        $builder = $this->setStatement($sql, $params);
        if ($builder->execute() && $builder->affected_rows > 0) {
            $ID = $builder->insert_id;
            $builder->close();
            $this->DisConnect();
            return $ID;
        } else {
            $builder->close();
            $this->DisConnect();
            return false;
        }
    }

    public function str_to_hex($string)
    {
        $hexstr = unpack('H*', $string);
        return array_shift($hexstr);
    }

    public function hex_to_str($string)
    {
        return hex2bin("$string");
    }
}