<?php

declare(strict_types=1);

namespace NoahVet\Reef\Test\A_Unit\Phpunit;

use NoahVet\Reef\Phpunit\HWIOauthKernelBrowser;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Component\BrowserKit\History;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\User\UserInterface;

class HWIOauthKernelBrowserTest extends TestCase
{
    public function testLogin(): void
    {
        $tokenStorage = new TokenStorage();
        $session = $this->getMockBuilder(SessionInterface::class)
            ->disableOriginalConstructor()
            ->getMock()
        ;

        $session->method('getName')
            ->willReturn('sessionName')
        ;

        $session->method('getId')
            ->willReturn('sessionId')
        ;

        $container = $this->getMockBuilder(ContainerInterface::class)
            ->disableOriginalConstructor()
            ->getMock()
        ;

        $container
            ->expects($this->exactly(3))
            ->method('has')
            ->willReturnCallback(function ($service) {
                return match ($service) {
                    'test.service_container', 'session' => true,
                    'session.factory' => false,
                    default => false
                };
            })
        ;

        $container
            ->expects($this->exactly(3))
            ->method('get')
            ->willReturnCallback(fn ($service) => match ($service) {
                'test.service_container' => $container,
                'security.untracked_token_storage' => $tokenStorage,
                'session' => $session,
                default => null
            })
        ;

        $kernel = $this->getMockBuilder(KernelInterface::class)
            ->disableOriginalConstructor()
            ->getMock()
        ;

        $kernel
            ->method('getContainer')
            ->willReturn($container)
        ;

        $history = $this->getMockBuilder(History::class)
            ->disableOriginalConstructor()
            ->getMock()
        ;

        $httpClient = new KernelBrowser(
            $kernel,
            [],
            $history,
        );

        $client = new HWIOauthKernelBrowser($httpClient);

        $user = $this->getMockBuilder(UserInterface::class)
            ->disableOriginalConstructor()
            ->getMock()
        ;

        $user->method('getRoles')
            ->willReturn(['ROLE_USER'])
        ;

        $client->loginUserOauth($user);

        self::assertSame($user, $tokenStorage->getToken()?->getUser());
    }
}
