<?php

namespace Opentalent\OtOptimizer\XClass\Core\Site;

use Opentalent\OtCore\Exception\NoSuchWebsiteException;
use Opentalent\OtCore\Website\OtWebsiteRepository;
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;

class SiteFinder extends \TYPO3\CMS\Core\Site\SiteFinder
{
    private $fallback;

    /**
     * Fetches all existing configurations as Site objects
     */
    public function __construct($siteConfiguration = null, $fallback = true)
    {
        $this->fallback = $fallback;
        if ($this->fallback) {
            parent::__construct($siteConfiguration);
        }
    }

    /**
     * Find a site by given root page id
     *
     * @param int $rootPageId the page ID (default language)
     * @return Site
     * @throws SiteNotFoundException
     * @internal only for usage in some places for managing Site Configuration, might be removed without further notice
     */
    public function getSiteByRootPageId(int $rootPageId): Site
    {
        if ($this->fallback) {
            return parent::getSiteByRootPageId($rootPageId);
        }

        $otWebsiteRepository = GeneralUtility::makeInstance(ObjectManager::class)->get(OtWebsiteRepository::class);
        try {
            $website = $otWebsiteRepository->getWebsiteByPageUid($rootPageId);
            return $otWebsiteRepository->generateWebsiteConfiguration($website);
        } catch (NoSuchWebsiteException $e) {
            throw new SiteNotFoundException('No site found for root page id ' . $rootPageId, 1521668882);
        }
    }

    /**
     * Find a site by given identifier
     *
     * @param string $identifier
     * @return Site
     * @throws SiteNotFoundException
     */
    public function getSiteByIdentifier(string $identifier): Site
    {
        if ($this->fallback) {
            return parent::getSiteByIdentifier($identifier);
        }

        $otWebsiteRepository = GeneralUtility::makeInstance(ObjectManager::class)->get(OtWebsiteRepository::class);

        try {
            $website = $otWebsiteRepository->getWebsiteByConfigIdentifier($identifier);
            return $otWebsiteRepository->generateWebsiteConfiguration($website);
        } catch (NoSuchWebsiteException $e) {
            throw new SiteNotFoundException('No site found for identifier ' . $identifier, 1521716628);
        }
    }

    /**
     *
     *
     * @param int $pageId
     * @param array $rootLine
     * @param string|null $mountPointParameter
     * @return Site
     * @throws SiteNotFoundException
     */
    public function getSiteByPageId(int $pageId, array $rootLine = null, string $mountPointParameter = null): Site
    {
        if ($this->fallback) {
            return parent::getSiteByPageId($pageId, $rootLine, $mountPointParameter);
        }

        $otWebsiteRepository = GeneralUtility::makeInstance(ObjectManager::class)->get(OtWebsiteRepository::class);
        try {
            $website = $otWebsiteRepository->getWebsiteByPageUid($pageId);
            return $otWebsiteRepository->generateWebsiteConfiguration($website);
        } catch (NoSuchWebsiteException $e) {
            throw new SiteNotFoundException('No site found in root line of page ' . $pageId, 1521716622);
        }
    }
}
