<?php

namespace App\Services\Wireguard;

class FakeWireguardHub implements WireguardHub
{
    /** @var array<string, string> pubkey => ip */
    private array $peers = [];

    private int $next = 2;

    public string $endpointValue = 'vpn.clupilot.test:51820';

    public string $publicKeyValue = 'HUBPUBLICKEY0000000000000000000000000000000=';

    /** Snapshots the tests can shape; defaults to "configured, never handshaked". */
    public array $snapshots = [];

    public function allocateIp(int $from = 1): string
    {
        // Der Zähler springt nach vorn, wenn ab einer höheren Stelle gesucht
        // wird, und läuft danach von dort weiter — sonst gäbe die Attrappe
        // zweimal dieselbe Adresse aus, sobald jemand einmal mit Versatz fragt.
        $this->next = max($this->next, $from);

        return '10.66.0.'.$this->next++;
    }

    public function addPeer(string $publicKey, string $ip): void
    {
        $this->peers[$publicKey] = $ip;
    }

    public function removePeer(string $publicKey): void
    {
        unset($this->peers[$publicKey]);
    }

    public function peers(): array
    {
        $peers = [];
        foreach ($this->peers as $publicKey => $ip) {
            $peers[$publicKey] = $this->snapshots[$publicKey] ?? new PeerSnapshot(
                publicKey: $publicKey,
                endpoint: null,
                allowedIps: $ip.'/32',
                latestHandshake: null,
                rxBytes: 0,
                txBytes: 0,
            );
        }

        return $peers;
    }

    public function endpoint(): string
    {
        return $this->endpointValue;
    }

    public function publicKey(): string
    {
        return $this->publicKeyValue;
    }

    /** Raw pubkey => ip map — what the tests assert on. Not the interface's
     *  peers(), which returns live snapshots. */
    public function peerIps(): array
    {
        return $this->peers;
    }
}
