<?php

class db
{
    private static $dbh;
    private static $error;
    private static $stmt;

    private static function connexion()
    {
        if (self::$dbh) {
            return;
        }

        $dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME;
        $options = array(
            PDO::ATTR_PERSISTENT => true,
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
        );

        try {
            self::$dbh = new PDO($dsn, DB_USER, DB_PASS, $options);
        } catch (PDOException $e) {
            self::$error = $e->getMessage();
            throw new Exception(self::$error);
        }
    }

    public static function version()
    {
        self::connexion();
        return self::$dbh->getAttribute(PDO::ATTR_SERVER_VERSION);
    }

    public static function query(string $query)
    {
        self::connexion();
        self::$stmt = self::$dbh->prepare($query);
    }

    public static function bind(string $param, $value = null, $type = null)
    {
        if (is_null($type)) {
            switch (true) {
                case is_int($value):
                    $type = PDO::PARAM_INT;
                    break;
                case is_bool($value):
                    $type = PDO::PARAM_BOOL;
                    break;
                case is_null($value):
                    $type = PDO::PARAM_NULL;
                    break;
                default:
                    $type = PDO::PARAM_STR;
            }
        }
        self::$stmt->bindValue($param, $value, $type);
    }

    public static function execute()
    {
        self::connexion();
        if (debug::isFile("sql")) {
            ob_start();
            $return = self::$stmt->execute();
            self::$stmt->debugDumpParams();
            $debugOutput = ob_get_clean();
            debug::logSession($debugOutput);
            return $return;
        } else {
            return self::$stmt->execute();
        }
    }

    public static function resultset()
    {
        self::execute();
        return self::$stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public static function single()
    {
        self::execute();
        return self::$stmt->fetch(PDO::FETCH_ASSOC);
    }

    public static function rowCount()
    {
        return self::$stmt->rowCount();
    }

    public static function lastInsertId()
    {
        self::connexion();
        return self::$dbh->lastInsertId();
    }

    public static function beginTransaction()
    {
        self::connexion();
        return self::$dbh->beginTransaction();
    }

    public static function endTransaction()
    {
        self::connexion();
        return self::$dbh->commit();
    }

    public static function cancelTransaction()
    {
        self::connexion();
        return self::$dbh->rollBack();
    }

    public static function debugDumpParams()
    {
        self::connexion();
        return self::$stmt->debugDumpParams();
    }

    public static function queryError()
    {
        self::connexion();
        $qError = self::$dbh->errorInfo();
        if (!is_null($qError[2])) {
            echo $qError[2];
        }
    }

    public static function getError()
    {
        return self::$error;
    }
}
