<?php

/**
 * Copyright 2024-2025 Simply.IN Sp. z o.o.
 *
 * NOTICE OF LICENSE
 *
 * Licensed under the EUPL-1.2 or later.
 * You may not use this work except in compliance with the Licence.
 *
 * Copy of the Licence is available at:
 * https://joinup.ec.europa.eu/software/page/eupl
 * It is bundled with this package in the file LICENSE.txt
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the Licence is distributed on an as is basis,
 * without warranties or conditions of any kind, either express or implied.
 * Check the Licence for the specific language governing permissions
 * and limitations under the License.
 *
 * @author   Simply.IN Sp. z o.o.
 * @copyright 2024-2025 Simply.IN Sp. z o.o.
 * @license   https://joinup.ec.europa.eu/software/page/eupl
 */

declare(strict_types=1);

namespace SimplyIn\Auth;

if (!defined('_PS_VERSION_')) {
    exit;
}

/**
 * A short-lived, non-reentrant mutex guarding the RSA registration handshake against concurrent
 * PHP-FPM workers. See {@see RsaRegistrationLock} for the production (DB-backed) implementation;
 * this seam exists so tests can substitute an in-memory double without a real database.
 */
interface RsaRegistrationLockInterface
{
    /**
     * Attempt to acquire the lock. Non-reentrant: calling this twice from the same holder without
     * releasing in between is not supported and implementations are expected to reject it loudly
     * (a programming error) rather than silently re-acquiring or blocking.
     *
     * @return bool true when the lock was acquired, false when another process already holds it
     *
     * @throws \Throwable on a programming-error misuse (reentrant acquire) or an underlying
     *                     technical failure (e.g. a DB error) — callers must not treat this as
     *                     "never throws"; {@see RsaRegistrar::doRegister()} is the reference caller
     *                     for how to handle both.
     */
    public function acquire(): bool;

    /**
     * Release the lock. Safe to call even when {@see acquire()} was never called or failed
     * (no-op in that case).
     *
     * @throws \Throwable on an underlying technical failure releasing an actually-held lock; on
     *                     failure the lock must still be considered held by the implementation
     *                     (so a caller that retries release() tries again instead of assuming it
     *                     is free).
     */
    public function release(): void;
}
