<?php declare(strict_types=1);

namespace Newland\Toubiz\Poi\Neos\Tests\Unit\Command;

use Neos\Flow\Tests\FunctionalTestCase;
use Newland\Toubiz\Api\Service\ServiceFactory;
use Newland\Toubiz\Api\Service\ServiceResult;
use Newland\Toubiz\Sync\Neos\Command\Helper\ConfigurationHelper;
use Newland\Toubiz\Sync\Neos\Command\OfferCommandController;
use PHPUnit\Framework\MockObject\MockObject;
use Newland\Toubiz\Api\Service\Tportal;

class OfferCommandControllerTest extends FunctionalTestCase
{
    protected static $testablePersistenceEnabled = true;

    /** @var OfferCommandController */
    private $subject;

    /** @var MockObject<Tportal\ApiService> */
    private $tportalApiService;

    public function setUp(): void
    {
        parent::setUp();

        $this->subject = $this->objectManager->get(OfferCommandController::class);

        $this->tportalApiService = $this->createMock(Tportal\ApiService::class);
        ServiceFactory::mock('Tportal/Api', $this->tportalApiService);
    }

    public function tearDown(): void
    {
        ServiceFactory::resetMocks();
        $this->objectManager->forgetInstance(ConfigurationHelper::class);
        parent::tearDown();
    }

    private function setServiceOptions(array $options): void
    {
        $configurationHelper = new ConfigurationHelper();
        $this->inject($configurationHelper, 'configuration', [ 'services' => $options ]);
        $this->inject($this->subject, 'configurationHelper', $configurationHelper);
    }

    public function testCallsCorrectMethodOnApiServiceToImportOffers(): void
    {
        $this->setServiceOptions([
             'Tportal/Api' => [
                 'clients' => [
                     'foo' => [ 'client' => 'foo' ]
                 ]
             ]
         ]);

        $this->tportalApiService->expects($this->once())
            ->method('fetchOffers');

        $this->subject->synchronizeCommand(true, false);
    }

    public function testPassesDownClientWhenImportingLodgings(): void
    {
        $this->setServiceOptions([
             'Tportal/Api' => [
                 'clients' => [
                     'foo' => [ 'client' => 'foo' ]
                 ]
             ]
         ]);

        $this->tportalApiService->method('fetchOffers')->willReturn(new ServiceResult());
        $this->tportalApiService->expects($this->once())
            ->method('setClientName')
            ->with($this->equalTo('foo'));

        $this->subject->synchronizeCommand(true, false);
    }

    public function testPassesDownLanguagesWhenImportingLodgings(): void
    {
        $this->setServiceOptions([
             'Tportal/Api' => [
                 'clients' => [
                     'foo' => [
                         'client' => 'foo',
                         'languages' => [ 'en', 'fr', 'es' ]
                     ]
                 ]
             ]
         ]);

        $this->tportalApiService->method('fetchOffers')->willReturn(new ServiceResult());
        $this->tportalApiService->expects($this->exactly(3))
            ->method('setLanguage')
            ->withConsecutive(
                [ $this->equalTo('en') ],
                [ $this->equalTo('fr') ],
                [ $this->equalTo('es') ]
            );

        $this->subject->synchronizeCommand(true, false);
    }

    public function testDefaultsToGerman(): void
    {
        $this->setServiceOptions([
             'Tportal/Api' => [
                 'clients' => [
                     'foo' => [ 'client' => 'foo' ]
                 ]
             ]
         ]);

        $this->tportalApiService->method('fetchOffers')->willReturn(new ServiceResult());
        $this->tportalApiService->expects($this->once())
            ->method('setLanguage')
            ->with($this->equalTo('de'));

        $this->subject->synchronizeCommand(true, false);
    }

}
