<?php

namespace apexl\Io\modules\install\services;

use apexl\Config\Configuration;
use apexl\Vault\Vault;

class databaseTools
{
    //@see https://stackoverflow.com/a/6549440/2412837

    /**
     * Function to determine if the provided database name is available.
     * @param $niceName mixed - the name of the database key in config, or the manual db config for connection
     * @throws \Exception
     */
    public function checkDBExists($niceName = 'default')
    {
        //first, we check if we have the database in config, and if we do, can we open a PDO connection?
        //catch the error if there is one, since this is a test we dont need to clog the logs with fails at this point.
        $config = Configuration::getInstance();
        if (is_array($niceName)) {
            //we've been passed manual details, so we expect to test with those.
        } elseif (isset($config->vault->databases) && isset($config->vault->databases->{$niceName})) {
            //We have db config so lets try that.
            //fire a blank PDO connection request. If we dont Fatal, the connection was made so null it and return true.
            //we only care about unknown database errors at this point - so check for that code (Right now we only use PDO so test for code 1049)
            //Any other errors we can just rethrow to pass back up.
            //no DB.
            //not a missing DB error? Throw the exception.
            try {
                $vault = $this->startCleanDB();
                $vault->initiateVault(
                    $niceName
                ); //fire a blank PDO connection request. If we dont Fatal, the connection was made so null it and return true.

                return $vault->testConnection($niceName);
            } catch (\Exception $e) {
                error_log("[IO Exception :: Database] -".$e->getCode()." | ".$e->getMessage());
                //we only care about unknown database errors at this point - so check for that code (Right now we only use PDO so test for code 1049)
                //Any other errors we can just rethrow to pass back up.
                if ($e->getCode() == 1049) {
                    return false; //no DB.
                }
                //not a missing DB error? Throw the exception.
                throw new \Exception($e->getMessage(), $e->getCode(), $e);
            }
        } else {
            return false;
        }

        return true;
    }

    protected function startCleanDB()
    {
        return clone Vault::getInstance();
    }

    public function processSchema($schema, $database = null)
    {
        if (!empty($schema)) {
            $vault = Vault::getInstance();
            //check if we have a database defined - if so, we need to select the database before continuing.
            if ($database) {
                $vault->setDefaultVault($database);
            }
            //get the db connection and
            //loop over the tables and install them. If they exist, we'll rely on a db error for now.
            foreach ($schema as $table => $config) {
                $vault->createTable($table, $config['_columns']);
            }
        }
    }
}
