<?php

namespace Opentalent\OtCore\Tests\Unit\Controller;

use Nimut\TestingFramework\TestCase\UnitTestCase;
use Opentalent\OtCore\Controller\SelectedSiteController;
use Opentalent\OtCore\Exception\NoSiteSelected;
use Opentalent\OtCore\Exception\NoSuchWebsiteException;
use Opentalent\OtCore\Website\OtPageRepository;
use Opentalent\OtCore\Website\OtWebsiteRepository;
use Prophecy\Argument;

class SelectedSiteControllerTest extends UnitTestCase
{
    private $controller;

    public function setUp() {
        $this->controller = new SelectedSiteController();
    }

    private function injectPageRepositoryWithSelectedUidAndMountpoints(?int $selectedUid, array $mountpoints = []) {
        $otPageRepository = $this->prophesize(OtPageRepository::class);

        if ($selectedUid != null) {
            $otPageRepository->getCurrentBeRootUid()->willReturn($selectedUid);
        } else {
            $otPageRepository->getCurrentBeRootUid()->willThrow(new NoSiteSelected());
        }
        $otPageRepository->getCurrentBeUserMountpoints()->shouldBeCalled()->willReturn($mountpoints);
        $this->controller->injectOtPageRepository($otPageRepository->reveal());

        $otWebsiteRepository = $this->prophesize(OtWebsiteRepository::class);
        $otWebsiteRepository->getWebsiteByPageUid(Argument::type('integer'))->willReturn(['uid' => 1, 'title' => 'Foo']);
        $this->controller->injectOtWebsiteRepository($otWebsiteRepository->reveal());

    }

    private function callActionMethodProxy() {
        $reflection = new \ReflectionObject($this->controller);
        $method = $reflection->getMethod('callActionMethod');
        $method->setAccessible(true);

        $argumentsProperty = $reflection->getProperty('preventPropagation');
        $argumentsProperty->setAccessible(true);;
        $argumentsProperty->setValue($this->controller, true);

        $method->invokeArgs($this->controller, []);

        $currentRootUidProperty = $reflection->getProperty('currentRootUid');
        $currentRootUidProperty->setAccessible(true);

        return $currentRootUidProperty->getValue($this->controller);
    }

    /**
     * If the current Be-user has only one website mounted,
     * then the currentRootUid should be this website root uid
     *
     * @test
     */
    public function callActionMethodForSingleSite() {

        $this->injectPageRepositoryWithSelectedUidAndMountpoints(null, [1]);

        $currentRootUid = $this->callActionMethodProxy();

        $this->assertEquals(1, $currentRootUid);
    }

    /**
     * If the current Be-user has many websites mounted and a website page is selected,
     * then the currentRootUid should be the currently selected website root page uid
     *
     * @test
     */
    public function callActionMethodForMultiSite() {

        $this->injectPageRepositoryWithSelectedUidAndMountpoints(2, [1, 2]);

        $currentRootUid = $this->callActionMethodProxy();

        $this->assertEquals(2, $currentRootUid);
    }

    /**
     * If the current Be-user has many websites mounted and no website page is selected,
     * then the currentRootUid should be null
     *
     * @test
     */
    public function callActionMethodForNoSite() {

        $this->injectPageRepositoryWithSelectedUidAndMountpoints(null, [1, 2]);

        $currentRootUid = $this->callActionMethodProxy();

        $this->assertNull($currentRootUid);
    }
}
