<?php

namespace App\Tests\Logger;

use App\Entity\Account;
use App\Entity\AuditLog;
use App\Logger\AppLogger;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\User\UserInterface;

#[AllowMockObjectsWithoutExpectations]
class AppLoggerTest extends TestCase
{
    private $entityManager;
    private $security;
    private $requestStack;
    private $logger;

    protected function setUp(): void
    {
        $this->entityManager = $this->createMock(EntityManagerInterface::class);
        $this->security = $this->createMock(Security::class);
        $this->requestStack = $this->createMock(RequestStack::class);

        $this->logger = new AppLogger(
            $this->entityManager,
            $this->security,
            $this->requestStack
        );
    }

    public function testRecordWithAccountUser()
    {
        $user = $this->createMock(Account::class);
        $this->security->method('getUser')->willReturn($user);

        $request = new Request();
        $request->headers->set('User-Agent', 'TestAgent');
        
        $this->requestStack->method('getCurrentRequest')->willReturn($request);

        $this->entityManager->expects($this->once())
            ->method('persist')
            ->with($this->isInstanceOf(AuditLog::class));
            
        $this->entityManager->expects($this->once())->method('flush');

        $this->logger->record('TEST_TYPE', 'Test Message');
    }

    public function testRecordWithNonAccountUser()
    {
        $user = $this->createMock(UserInterface::class);
        $this->security->method('getUser')->willReturn($user);

        $this->entityManager->expects($this->never())->method('persist');
        $this->entityManager->expects($this->never())->method('flush');

        $this->logger->record('TEST_TYPE', 'Test Message');
    }
    
    public function testRecordWithNoRequest()
    {
        $user = $this->createMock(Account::class);
        $this->security->method('getUser')->willReturn($user);

        $this->requestStack->method('getCurrentRequest')->willReturn(null);

        $this->entityManager->expects($this->once())
            ->method('persist')
            ->with($this->callback(function(AuditLog $log) {
                return $log->getPath() === 'CLI/Internal';
            }));
            
        $this->entityManager->expects($this->once())->method('flush');

        $this->logger->record('TEST_TYPE', 'Test Message');
    }
}
