<?php /** @noinspection PhpUnhandledExceptionInspection */

namespace App\Tests\Unit\Service\Typo3;

use App\Service\Typo3\Typo3Service;
use PHPUnit\Framework\TestCase;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;

class TestableTypo3Service extends Typo3Service {
    public function sendCommand(string $route, array $parameters): ResponseInterface { return parent::sendCommand($route, $parameters); }
}

class Typo3ServiceTest extends TestCase
{
    private HttpClientInterface $typo3Client;

    public function setUp(): void {
        $this->typo3Client = $this->getMockBuilder(HttpClientInterface::class)->disableOriginalConstructor()->getMock();
    }

    /**
     * @see Typo3Service::sendCommand()
     */
    public function testSendCommand(): void
    {
        $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();

        $this->typo3Client
            ->expects(self::once())
            ->method('request')
            ->with('GET', '/typo3/index.php?route=foo&param=bar')
            ->willReturn($response);

        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
            ->setConstructorArgs([$this->typo3Client])
            ->setMethodsExcept(['sendCommand'])
            ->getMock();

        $typo3Service->sendCommand('foo', ['param' => 'bar']);
    }

    /**
     * @see Typo3Service::clearSiteCache()
     */
    public function testClearSiteCache(): void
    {
        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
            ->setMethodsExcept(['clearSiteCache'])
            ->disableOriginalConstructor()
            ->getMock();


        $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
        $typo3Service->expects(self::once())
            ->method('sendCommand')->
            with('/otadmin/site/clear-cache', ['organization-id' => 1])
            ->willReturn($response);

        $typo3Service->clearSiteCache(1);
    }

    /**
     * @see Typo3Service::createSite()
     */
    public function testCreateSite(): void
    {
        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
            ->setMethodsExcept(['createSite'])
            ->disableOriginalConstructor()
            ->getMock();

        $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
        $typo3Service->expects(self::once())
            ->method('sendCommand')->
            with('/otadmin/site/create', ['organization-id' => 1])
            ->willReturn($response);

        $typo3Service->createSite(1);
    }

    /**
     * @see Typo3Service::updateSite()
     */
    public function testUpdateSite(): void
    {
        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
            ->setMethodsExcept(['updateSite'])
            ->disableOriginalConstructor()
            ->getMock();


        $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
        $typo3Service->expects(self::once())
            ->method('sendCommand')->
            with('/otadmin/site/update', ['organization-id' => 1])
            ->willReturn($response);

        $typo3Service->updateSite(1);
    }

    /**
     * @see Typo3Service::deleteSite()
     */
    public function testDeleteSite(): void
    {
        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
            ->setMethodsExcept(['deleteSite'])
            ->disableOriginalConstructor()
            ->getMock();


        $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
        $typo3Service->expects(self::once())
            ->method('sendCommand')->
            with('/otadmin/site/delete', ['organization-id' => 1])
            ->willReturn($response);

        $typo3Service->deleteSite(1);
    }

    /**
     * @see Typo3Service::undeleteSite()
     */
    public function testUndeleteSite(): void
    {
        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
            ->setMethodsExcept(['undeleteSite'])
            ->disableOriginalConstructor()
            ->getMock();


        $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
        $typo3Service->expects(self::once())
            ->method('sendCommand')->
            with('/otadmin/site/undelete', ['organization-id' => 1])
            ->willReturn($response);

        $typo3Service->undeleteSite(1);
    }

    /**
     * @see Typo3Service::setSiteDomain()
     */
    public function testSetSiteDomain(): void
    {
        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
            ->setMethodsExcept(['setSiteDomain'])
            ->disableOriginalConstructor()
            ->getMock();


        $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
        $typo3Service->expects(self::once())
            ->method('sendCommand')->
            with('/otadmin/site/set-domain', ['organization-id' => 1, 'domain' => 'new-domain'])
            ->willReturn($response);

        $typo3Service->setSiteDomain(1, 'new-domain', false);
    }

    /**
     * @see Typo3Service::setSiteDomain()
     */
    public function testSetSiteDomainWithRedirection(): void
    {
        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
            ->setMethodsExcept(['setSiteDomain'])
            ->disableOriginalConstructor()
            ->getMock();


        $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
        $typo3Service->expects(self::once())
            ->method('sendCommand')->
            with('/otadmin/site/set-domain', ['organization-id' => 1, 'domain' => 'new-domain', 'redirect' => 1])
            ->willReturn($response);

        $typo3Service->setSiteDomain(1, 'new-domain', true);
    }

    /**
     * @see Typo3Service::resetSitePerms()
     */
    public function testResetSitePerms(): void
    {
        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
            ->setMethodsExcept(['resetSitePerms'])
            ->disableOriginalConstructor()
            ->getMock();


        $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
        $typo3Service->expects(self::once())
            ->method('sendCommand')->
            with('/otadmin/site/reset-perms', ['organization-id' => 1])
            ->willReturn($response);

        $typo3Service->resetSitePerms(1);
    }

    /**
     * @see Typo3Service::getSiteStatus()
     */
    public function testGetSiteStatus(): void
    {
        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
            ->setMethodsExcept(['getSiteStatus'])
            ->disableOriginalConstructor()
            ->getMock();


        $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
        $typo3Service->expects(self::once())
            ->method('sendCommand')->
            with('/otadmin/site/status', ['organization-id' => 1])
            ->willReturn($response);

        $typo3Service->getSiteStatus(1);
    }

    /**
     * @see Typo3Service::addRedirection()
     */
    public function testAddRedirection(): void
    {
        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
            ->setMethodsExcept(['addRedirection'])
            ->disableOriginalConstructor()
            ->getMock();

        $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
        $typo3Service->expects(self::once())
            ->method('sendCommand')->
            with('/otadmin/redirect/add', ['from-domain' => 'foo', 'to-domain' => 'bar'])
            ->willReturn($response);

        $typo3Service->addRedirection('foo', 'bar');
    }
}
