<?php
namespace boru\ai\Persistence\Db;

use boru\dhdb\dhDB;
use boru\dhutils\dhGlobal;

class DbConnection
{
    /** @var DbConfig */
    protected $config;

    public function __construct(DbConfig $config = null)
    {
        $this->config = $config ? $config : new DbConfig();
    }

    public function config(DbConfig $config = null)
    {
        if ($config !== null) {
            $this->config = $config;
            return $this;
        }
        return $this->config;
    }

    public function db($dbConfig = null)
    {
        if ($dbConfig !== null) {
            return dhGlobal::db($dbConfig);
        }

        if (!dhGlobal::db() && $this->config()->get('use', false)) {
            return dhGlobal::db($this->config()->toArray());
        }

        return dhGlobal::db();
    }

    public function run($sql, array $params = array(), $dbConfig = null)
    {
        $db = $this->db($dbConfig);
        $statement = $db->run($sql, $params);

        if (is_object($statement) && method_exists($statement, 'isError') && $statement->isError()) {
            $error = method_exists($statement, 'getError') ? $statement->getError() : null;
            $message = 'Database query failed';
            $code = 0;
            $interpolated = null;

            if (is_object($error)) {
                if (method_exists($error, 'getMessage')) {
                    $message = $error->getMessage();
                } elseif (isset($error->message)) {
                    $message = $error->message;
                }

                if (method_exists($error, 'getCode')) {
                    $code = $error->getCode();
                } elseif (isset($error->code)) {
                    $code = $error->code;
                }

                if (method_exists($error, 'getInterpolated')) {
                    $interpolated = $error->getInterpolated();
                } elseif (isset($error->interpolated)) {
                    $interpolated = $error->interpolated;
                }
            }

            throw new DbQueryException($message, (int)$code, $sql, $params, $interpolated);
        }

        return $statement;
    }
}
