<?php

namespace apexl\Io\modules\install\services;

use apexl\Vault\Vault;
use Exception;
use function apexl\Io\config;

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

    public function __construct(private Vault $vault) {}

    /**
     * Function to determine if the provided database name is available.
     * @throws Exception
     */
    public function checkDBExists(string $dbName = 'default'): bool
    {
        //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.
        if (config(sprintf('vault.databases.%s', $dbName))) {
            //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 {
                $this->vault->resetVaults();
                $this->vault->initiateVault(
                    $dbName
                ); //fire a blank PDO connection request. If we dont Fatal, the connection was made so null it and return true.

                return $this->vault->testConnection($dbName);
            } catch (Exception $e) {
                error_log(sprintf('[IO Exception :: Database] -%s | %s', $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);
            }
        }

        return false;

    }
}
