<?php

declare(strict_types=1);

namespace Srp\Tests;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

/**
 * Contract test for redirect/redirect_payload.php — the 5-field CSV token
 * (click_id,country_code,user_agent,ip_address,user_lp) carried in the `rk`
 * param to /_meetups/. Decode MUST fail closed (null) on anything malformed.
 */
final class RedirectPayloadTest extends TestCase
{
    public function testEncodeDecodeRoundTrip(): void
    {
        $token = srp_redirect_payload_encode('ABC123', 'us', 'mobile', '203.0.113.7', 'lp1');
        $decoded = srp_redirect_payload_decode($token);

        self::assertSame([
            'click_id' => 'ABC123',
            'country_code' => 'us',
            'user_agent' => 'mobile',
            'ip_address' => '203.0.113.7',
            'user_lp' => 'lp1',
        ], $decoded);
    }

    public function testEncodedTokenIsUrlSafe(): void
    {
        $token = srp_redirect_payload_encode('a', 'b', 'c', 'd', 'e');

        self::assertMatchesRegularExpression('/^[A-Za-z0-9_-]+$/', $token);
    }

    /**
     * @return array<string, array{0: mixed}>
     */
    public static function rejectedInputs(): array
    {
        return [
            'null' => [null],
            'array (non-scalar)' => [['x']],
            'empty string' => [''],
            'non-base64url chars' => ['not valid!'],
            'over 1024 chars' => [str_repeat('A', 1025)],
        ];
    }

    #[DataProvider('rejectedInputs')]
    public function testDecodeFailsClosed(mixed $input): void
    {
        self::assertNull(srp_redirect_payload_decode($input));
    }

    public function testDecodeRejectsWrongFieldCount(): void
    {
        // Only three CSV fields instead of the required five.
        $token = srp_redirect_base64url_encode('a,b,c');

        self::assertNull(srp_redirect_payload_decode($token));
    }
}
