<?php

namespace Sibs\Sibs\DB;

use Magento\Framework\App\ObjectManager;

class SibsDB
{
    /**
     * Construct
     */
    public function __construct()
    {
    }

    /**
     * Clone
     */
    private function __clone()
    {
    }

    /**
     * Wakeup
     */
    public function __wakeup()
    {
    }

    /**
     * Retrieve object manager
     *
     * @return ObjectManager
     * @throws \RuntimeException
     */
    private static function getInstance()
    {
        return ObjectManager::getInstance();
    }

    /**
     * Gets data from flattened data
     *
     * @param string $key
     * @param mixed $defaultValue
     * @return mixed|null
     * @throws FileSystemException
     * @throws RuntimeException
     */
    public static function get($objectNamespace)
    {
        return self::getInstance()->get($objectNamespace);
    }

    /**
     * Create connection adapter instance
     *
     * @param array $connectionConfig
     * @return \Magento\Framework\DB\Adapter\AdapterInterface
     * @throws \InvalidArgumentException
     */
    public static function create($objectNamespace)
    {
        return self::getInstance()->create($objectNamespace);
    }

    /**
     * Get Magento ResourceConnection
     *
     * @return \Magento\Framework\App\ResourceConnection
     */
    private static function getResource()
    {
        return self::get('Magento\Framework\App\ResourceConnection');
    }

    /**
     * Get resource table name, validated by db adapter.
     *
     * @param string|string[] $modelEntity
     * @param string $connectionName
     * @return string
     */
    public static function getTableName($tableBaseName)
    {
        return self::getResource()->getTableName($tableBaseName);
    }

    /**
     * Returns the underlying database connection object or resource.
     * If not presently connected, this initiates the connection.
     *
     * @return object|resource|null
     */
    public static function getConnection()
    {
        return self::getResource()->getConnection();
    }

    /**
     * Prepares and executes an SQL statement with bound data.
     *
     * @param  mixed  $sql  The SQL statement with placeholders.
     *                      May be a string or Zend_Db_Select.
     * @param  mixed  $bind An array of data to bind to the placeholders.
     * @return Zend_Db_Statement_Interface
     */
    public static function query($sql, $bind = [])
    {
        return self::getConnection()->query($sql, $bind);
    }

    /**
     * Inserts a table row with specified data.
     *
     * @param mixed $table The table to insert data into.
     * @param array $bind Column-value pairs.
     * @return int The number of affected rows.
     * @throws Zend_Db_Adapter_Exception
     */
    public static function insert($table, array $bind)
    {
        return self::getConnection()->insert($table, $bind);
    }

    /**
     * Updates table rows with specified data based on a WHERE clause.
     *
     * @param  mixed        $table The table to update.
     * @param  array        $bind  Column-value pairs.
     * @param  mixed        $where UPDATE WHERE clause(s).
     * @return int          The number of affected rows.
     * @throws Zend_Db_Adapter_Exception
     */
    public static function update($table, array $bind, $where = '')
    {
        return self::getConnection()->update($table, $bind, $where);
    }

    /**
     * Deletes table rows based on a WHERE clause.
     *
     * @param  mixed        $table The table to update.
     * @param  mixed        $where DELETE WHERE clause(s).
     * @return int          The number of affected rows.
     */
    public static function delete($table, $where = '')
    {
        return self::getConnection()->delete($table, $where);
    }

    /**
     * Fetches all SQL result rows as a sequential array.
     * Uses the current fetchMode for the adapter.
     *
     * @param string|Zend_Db_Select $sql  An SQL SELECT statement.
     * @param mixed                 $bind Data to bind into SELECT placeholders.
     * @param mixed                 $fetchMode Override current fetch mode.
     * @return array
     */
    public static function fetchAll($sql, $bind = [], $fetchMode = null)
    {
        return self::getConnection()->fetchAll($sql, $bind, $fetchMode);
    }

    /**
     * Fetches the first row of the SQL result.
     * Uses the current fetchMode for the adapter.
     *
     * @param string|Zend_Db_Select $sql An SQL SELECT statement.
     * @param mixed $bind Data to bind into SELECT placeholders.
     * @param mixed                 $fetchMode Override current fetch mode.
     * @return mixed Array, object, or scalar depending on fetch mode.
     */
    public static function fetchRow($sql, $bind = [], $fetchMode = null)
    {
        return self::getConnection()->fetchRow($sql, $bind, $fetchMode);
    }

    /**
     * Fetches all SQL result rows as an associative array.
     *
     * The first column is the key, the entire row array is the
     * value.  You should construct the query to be sure that
     * the first column contains unique values, or else
     * rows with duplicate values in the first column will
     * overwrite previous data.
     *
     * @param string|Zend_Db_Select $sql An SQL SELECT statement.
     * @param mixed $bind Data to bind into SELECT placeholders.
     * @return array
     */
    public static function fetchAssoc($sql, $bind = [])
    {
        return self::getConnection()->fetchAssoc($sql, $bind);
    }

    /**
     * Fetches the first column of all SQL result rows as an array.
     *
     * @param string|Zend_Db_Select $sql An SQL SELECT statement.
     * @param mixed $bind Data to bind into SELECT placeholders.
     * @return array
     */
    public static function fetchCol($sql, $bind = [])
    {
        return self::getConnection()->fetchCol($sql, $bind);
    }

    /**
     * Fetches all SQL result rows as an array of key-value pairs.
     *
     * The first column is the key, the second column is the
     * value.
     *
     * @param string|Zend_Db_Select $sql An SQL SELECT statement.
     * @param mixed $bind Data to bind into SELECT placeholders.
     * @return array
     */
    public static function fetchPairs($sql, $bind = [])
    {
        return self::getConnection()->fetchPairs($sql, $bind);
    }

    /**
     * Fetches the first column of the first row of the SQL result.
     *
     * @param string|Zend_Db_Select $sql An SQL SELECT statement.
     * @param mixed $bind Data to bind into SELECT placeholders.
     * @return string
     */
    public static function fetchOne($sql, $bind = [])
    {
        return self::getConnection()->fetchOne($sql, $bind);
    }

    /**
     * Get the LastInserted ID.
     *
     * @param mixed        $table The table to update.
     * @param mixed        $primaryKey Primary key to return.
     * @return string
     */
    public static function lastInsertId($table = null, $primaryKey = null)
    {
        return self::getConnection()->lastInsertId($table, $primaryKey);
    }
}
