<?php

namespace Phlaym\Roastmonday\DB;

use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;

class BaseDB
{
    protected LoggerInterface $logger;

    protected static int $ERR_DUPLICATE_ENTRY = 1062;
    protected static int $ERR_CONNECTION_LIMIT = 1062;
    protected static int $ERR_TIMEOUT = 2002;

    //TODO: Implement a better system
    public static int $SUCCESS = 0;
    public static int $SKIPPED_DUPLICATE = 1;
    public static int $TRIED_INSERT_DUPLICATE = 2;

    protected $conn = null;

    public function __construct(
        string $servername,
        string $db,
        string $username,
        string $password,
        ?LoggerInterface $logger
    ) {
        if ($logger === null) {
            $this->logger = new NullLogger();
        } else {
            $this->logger = $logger;
        }
        try {
            $this->conn = new \PDO(
                'mysql:host='
                . $servername
                . ';dbname='
                . $db,
                $username,
                $password
            );
        } catch (\PDOException $Exception) {
            if (count($Exception->errorInfo) >= 2 && $Exception->errorInfo[1] === DB::$ERR_CONNECTION_LIMIT) {
                throw new ConnectionLimitReached();
            } elseif (count($Exception->errorInfo) >= 2 && $Exception->errorInfo[1] === DB::$ERR_TIMEOUT) {
                throw new OperationTimedOutException($Exception->getMessage());
            } else {
                #echo json_encode($Exception->errorInfo);
                throw new DBException($Exception->getMessage());
            }
        }
        $this->conn->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
    }

    /**
     * Get name of the constant for the result value
     * @param integer $value
     *
     * @return string
     */
    public static function getResultName(int $value)
    {
        $constantNames = array_flip(
            array_filter(
                (new \ReflectionClass(static::class))->getStaticProperties(),
                static fn($v) => is_scalar($v), // only int/string
            ),
        );

        return $constantNames[$value] ?? null;
    }
}
