<?php
namespace apexl\Io\modules\install\services;

use apexl\Config\Singleton;
use \apexl\Vault\Vault;

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

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

    /**
     * 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 = Singleton::getInstance();
        if(is_array($niceName)){
            //we've been passed manual details, so we expect to test with those.
        } else {
            if(isset($config->vault->databases) && isset($config->vault->databases->{$niceName})){
                //We have db config so lets try that.
                try {
                    $vault = $this->startCleanDB();
                    $vault->initiateVault($niceName);
                    $exists = $vault->testConnection($niceName); //fire a blank PDO connection request. If we dont Fatal, the connection was made so null it and return true.
                    return $exists;
                } 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());
                }
            } else {
                return FALSE;
            }
        }
        return TRUE;
    }

    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']);
            }
        }
    }
}