<?php

namespace App\Services\Wireguard;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use SensitiveParameter;

/**
 * Short-lived server-side holding area for a plaintext config on its way to the
 * browser.
 *
 * Livewire round-trips every public property in the component snapshot — and
 * the VPN page polls every five seconds. Keeping the private key in a public
 * property would therefore send that credential over the wire again and again,
 * and park it in the DOM's snapshot attribute for the life of the page. The
 * component holds an opaque token instead; the plaintext is looked up during
 * render and never enters the snapshot.
 */
final class ConfigHandoff
{
    private const PREFIX = 'vpn:handoff:';

    private const TTL_SECONDS = 600;

    /** @param string|null $token reuse a handle the caller already handed out */
    public static function put(#[SensitiveParameter] string $plaintext, ?string $token = null): string
    {
        $token ??= Str::random(40);
        Cache::put(self::PREFIX.$token, $plaintext, self::TTL_SECONDS);

        return $token;
    }

    public static function get(?string $token): ?string
    {
        return $token === null ? null : Cache::get(self::PREFIX.$token);
    }

    public static function forget(?string $token): void
    {
        if ($token !== null) {
            Cache::forget(self::PREFIX.$token);
        }
    }
}
