<?php

declare(strict_types=1);

final class HyroCsrf
{
    private const SESSION_KEY = 'hyro_csrf_token';

    public static function startSession(): void
    {
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }
    }

    public static function token(): string
    {
        self::startSession();

        if (
            empty($_SESSION[self::SESSION_KEY]) ||
            !is_string($_SESSION[self::SESSION_KEY])
        ) {
            $_SESSION[self::SESSION_KEY] =
                bin2hex(random_bytes(32));
        }

        return $_SESSION[self::SESSION_KEY];
    }

    public static function input(): string
    {
        return sprintf(
            '<input type="hidden" name="_token" value="%s">',
            hyro_escape(self::token())
        );
    }

    public static function verify(
        ?string $submittedToken
    ): bool {
        self::startSession();

        $storedToken =
            $_SESSION[self::SESSION_KEY] ?? '';

        return is_string($storedToken)
            && is_string($submittedToken)
            && $submittedToken !== ''
            && hash_equals(
                $storedToken,
                $submittedToken
            );
    }
}
