<?php

namespace App\Tests\Unit\Service\File\Storage;

use App\Entity\Core\File;
use App\Enum\Core\FileHostEnum;
use App\Service\ApiLegacy\ApiLegacyRequestService;
use App\Service\File\Storage\ApiLegacyStorage;
use App\Service\Utils\UrlBuilder;
use Liip\ImagineBundle\Imagine\Data\DataManager;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

class ApiLegacyStorageTest extends TestCase
{
    private ApiLegacyRequestService|MockObject $apiLegacyRequestService;
    private ApiLegacyRequestService|MockObject $dataManager;
    private ApiLegacyRequestService|MockObject $urlBuilder;

    public function setUp(): void
    {
        $this->apiLegacyRequestService = $this->getMockBuilder(ApiLegacyRequestService::class)
            ->disableOriginalConstructor()
            ->getMock();
        $this->dataManager = $this->getMockBuilder(DataManager::class)->disableOriginalConstructor()->getMock();
        $this->urlBuilder = $this->getMockBuilder(UrlBuilder::class)->disableOriginalConstructor()->getMock();
    }

    public function getApiLegacyStorageMockFor(string $methodName): ApiLegacyStorage|MockObject
    {
        return $this
            ->getMockBuilder(ApiLegacyStorage::class)
            ->setConstructorArgs([$this->apiLegacyRequestService, $this->dataManager, $this->urlBuilder, 'url', 'publicUrl'])
            ->setMethodsExcept([$methodName])
            ->getMock();
    }

    public function testExists(): void
    {
        $apiLegacyStorage = $this->getApiLegacyStorageMockFor('exists');

        $this->expectException(\RuntimeException::class);
        $this->expectExceptionMessage('not implemented error');

        $file = $this->getMockBuilder(File::class)->getMock();

        $apiLegacyStorage->exists($file);
    }

    public function testRead(): void
    {
        $apiLegacyStorage = $this->getApiLegacyStorageMockFor('read');

        $file = $this->getMockBuilder(File::class)->getMock();
        $file->method('getId')->willReturn(123);

        $this->apiLegacyRequestService
            ->expects(self::once())
            ->method('getContent')
            ->with('_internal/secure/files/123')
            ->willReturn('xyz');

        $result = $apiLegacyStorage->read($file);

        $this->assertEquals('xyz', $result);
    }

    public function testGetImageUrl(): void
    {
        $apiLegacyStorage = $this->getApiLegacyStorageMockFor('getImageUrl');

        $file = $this->getMockBuilder(File::class)->getMock();
        $file->method('getId')->willReturn(123);

        $this->apiLegacyRequestService
            ->expects(self::once())
            ->method('getContent')
            ->with('api/files/123/download/md?relativePath=1')
            ->willReturn('xyz');

        $this->assertEquals(
            'publicUrl/xyz',
            $apiLegacyStorage->getImageUrl($file, 'md', false)
        );
    }

    public function testGetImageUrlRelativePath(): void
    {
        $apiLegacyStorage = $this->getApiLegacyStorageMockFor('getImageUrl');

        $file = $this->getMockBuilder(File::class)->getMock();
        $file->method('getId')->willReturn(123);

        $this->apiLegacyRequestService
            ->expects(self::once())
            ->method('getContent')
            ->with('api/files/123/download/lg?relativePath=1')
            ->willReturn('xyz');

        $this->assertEquals(
            'url/xyz',
            $apiLegacyStorage->getImageUrl($file, 'lg', true)
        );
    }

    public function testSupport(): void
    {
        $apiLegacyStorage = $this->getApiLegacyStorageMockFor('support');

        $file1 = $this->getMockBuilder(File::class)->getMock();
        $file1->method('getHost')->willReturn(FileHostEnum::API1);

        $file2 = $this->getMockBuilder(File::class)->getMock();
        $file2->method('getHost')->willReturn(FileHostEnum::AP2I);

        $this->assertTrue($apiLegacyStorage->support($file1));
        $this->assertFalse($apiLegacyStorage->support($file2));
    }

    public function testDeleteOrganizationFiles(): void
    {
        $apiLegacyStorage = $this->getApiLegacyStorageMockFor('deleteOrganizationFiles');

        $this->apiLegacyRequestService
            ->expects(self::once())
            ->method('get')
            ->with('/_internal/request/organization-files/delete/123');

        $apiLegacyStorage->deleteOrganizationFiles(123);
    }

    public function testDeletePersonFiles(): void
    {
        $apiLegacyStorage = $this->getApiLegacyStorageMockFor('deletePersonFiles');

        $this->apiLegacyRequestService
            ->expects(self::once())
            ->method('get')
            ->with('/_internal/request/person-files/delete/123');

        $apiLegacyStorage->deletePersonFiles(123);
    }
}
