<?php

namespace Velis\Db;

use PDO;
use Velis\App;

class SnowflakePdo extends Snowflake
{
    /**
     * {@inheritDoc}
     */
    public function connect(array &$profilerInfo = null): self
    {
        $innerCall = false;
        if ($this->_debug && $profilerInfo === null) {
            $profilerInfo = [];
            $profilerInfo['query'] = 'CONNECT';
            $profilerInfo['caller'] = $this->_getCaller();
            $profilerInfo['func'] = __FUNCTION__;
            $profilerInfo['startTime'] = $this->getCurrentLifeTime();
            $profilerInfo['server'] = $this->_currentHost;
        } else {
            $innerCall = true;
        }

        if (!$this->_connectionParams) {
            $this->_connectionParams = App::$config->get('snowflake');
        }

        $this->_pdo = match ($this->_connectionParams->get('passphrase') !== null) {
            true => $this->keyPairConnection(),
            default =>$this->passwordConnection()
        };

        $database = $this->_connectionParams->get('database');

        $this->_currentHost = $database . '/' . $this->_connectionParams->get('warehouse');

        if (App::$config->hasTimezoneSupport() && App::$user) {
            $this->_pdo->exec("ALTER SESSION SET TIMEZONE='" . App::$user->getTimezone() . "'");
        }

        if ($this->_debug) {
            $profilerInfo['info'] = "Connected to "
                . $database
                . "@" . $this->_connectionParams->server;
            if (!$innerCall && $this->shouldLogToProfiler()) {
                $this->_profiler->addRow($profilerInfo);
            }
        }

        $this->_pdo->exec('USE DATABASE ' . $database);
        if ($this->_connectionParams->get('schema')) {
            $this->_pdo->exec('USE SCHEMA ' . $this->_connectionParams->get('schema'));
        }

        return $this;
    }


    private function passwordConnection(): PDO
    {
        $account = $this->_connectionParams->get('account');
        $region = $this->_connectionParams->get('region');
        $dsn = sprintf('snowflake:account=%s;region=%s', $account, $region);
        $user = $this->_connectionParams->get('user');
        $password = $this->_connectionParams->get('password');
        return new PDO($dsn, $user, $password);
    }


    private function keyPairConnection(): PDO
    {
        $account = $this->_connectionParams->get('account');
        $region = $this->_connectionParams->get('region');
        $keyFile = ROOT_PATH . $this->_connectionParams->get('key_file');
        $passphrase = $this->_connectionParams->get('passphrase');
        $user = $this->_connectionParams->get('user');
        $dsn = sprintf(
            'snowflake:account=%s.%s;authenticator=SNOWFLAKE_JWT;priv_key_file=%s;priv_key_file_pwd=%s',
            $account,
            $region,
            $keyFile,
            $passphrase
        );
        return new PDO($dsn, $user, "");
    }

    public function disconnect(): self
    {
        $this->_pdo = null;

        return $this;
    }

    public function isConnected(): bool
    {
        return $this->_pdo !== null;
    }
}
