<?php

use App\Models\ProviderConnection;
use App\Models\ProviderCredential;
use App\Services\Providers\CredentialManager;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

it('returns client credentials from encrypted payload', function (): void {
    $connection = ProviderConnection::factory()->dedicated()->create([
        'entra_tenant_id' => fake()->uuid(),
    ]);

    ProviderCredential::factory()->create([
        'provider_connection_id' => $connection->getKey(),
        'payload' => [
            'client_id' => 'client-id',
            'client_secret' => 'client-secret',
        ],
    ]);

    $manager = app(CredentialManager::class);

    expect($manager->getClientCredentials($connection))
        ->toBe([
            'client_id' => 'client-id',
            'client_secret' => 'client-secret',
        ]);
});

it('rejects credential payload that does not match the connection scope', function (): void {
    $connection = ProviderConnection::factory()->dedicated()->create([
        'entra_tenant_id' => 'tenant-a',
    ]);

    ProviderCredential::factory()->create([
        'provider_connection_id' => $connection->getKey(),
        'payload' => [
            'managed_environment_id' => 'tenant-b',
            'client_id' => 'client-id',
            'client_secret' => 'client-secret',
        ],
    ]);

    $manager = app(CredentialManager::class);

    $manager->getClientCredentials($connection);
})->throws(InvalidArgumentException::class);

it('rejects resolving dedicated credentials for platform connections', function (): void {
    $connection = ProviderConnection::factory()->platform()->create([
        'entra_tenant_id' => 'tenant-a',
    ]);

    ProviderCredential::factory()->create([
        'provider_connection_id' => $connection->getKey(),
        'payload' => [
            'client_id' => 'client-id',
            'client_secret' => 'client-secret',
        ],
    ]);

    $manager = app(CredentialManager::class);

    $manager->getClientCredentials($connection);
})->throws(InvalidArgumentException::class);

it('upserts client secret credentials and never serializes the payload', function (): void {
    $connection = ProviderConnection::factory()->dedicated()->create();

    $manager = app(CredentialManager::class);

    $credential = $manager->upsertClientSecretCredential(
        connection: $connection,
        clientId: 'client-id',
        clientSecret: 'client-secret',
    );

    expect($credential->type)->toBe('client_secret');
    expect($credential->payload)->toBe([
        'client_id' => 'client-id',
        'client_secret' => 'client-secret',
    ]);

    expect($credential->toArray())->not->toHaveKey('payload');

    expect((string) $credential->getRawOriginal('payload'))
        ->not->toContain('client-secret')
        ->not->toContain('client_id');
});
