<?php
use myty\modules\core\data\Status;
use myty\modules\core\net\HttpHeader;
use myty\modules\core\ContentType;
use myty\modules\core\utils\FileUtils;
use myty\modules\lang\Locale;
use myty\modules\nav\tyNavSettings;
use myty\modules\navigation\models\Domain;
use myty\modules\navigation\Navigation;
use myty\modules\navigation\repositories\DomainRepository;
use myty\modules\sitemap\SitemapUrl;
use myty\tyConfig;

/**
 * Domain-Umleitung prüfen
 */
include_once(__DIR__.'/../runtime.inc.php');
$runtime = tyRuntime::getInstance();
$requestUri = $runtime->getRequestUri();
$installPath = $runtime->installPath();
$rootPath = $runtime->documentRootPath();
/** @var Navigation $navigation */
$navigation = $runtime->getSingleton(Navigation::class);
$domain = $navigation->getCurrentDomain();
if ($domain === null) {
	HttpHeader::setStatus(HttpHeader::NOT_FOUND);
	exit;
}

$cacheDir = $runtime->cachePath().'/sitemaps';
$cacheTime = HttpHeader::EXPIRATION_1D;
$cachFile = $cacheDir.'/'.$domain->getName().'.xml';
$renew = isset($_GET['renew']);

try {
    HttpHeader::setCacheControlMaxAge($cacheTime);
    HttpHeader::setContentType(ContentType::XML);

    if( !$renew && is_readable($cachFile) && ( time() - filemtime($cachFile) <  $cacheTime ) ){
        readfile($cachFile);
    } else {

	    include_once($installPath.'/tylib.php');
        include_once($installPath.'/topic.compat.inc.php');
	    include_once($installPath.'/database.php');
	    include_once($installPath.'/modules/user/inc.php');

	    $em = $runtime->getEntityManager();
        $client = $runtime->getCurrentClient();
	    $clientId = $client->getId();
		$modulesConf = tyConfig::$data['modules'];
        $frontendLanguage = null;

		/** @var DomainRepository $domainRepo */
	    $domainRepo = $em->getRepository(Domain::class);
	    //Load the domain settings which are not part of the cached domain object
	    $domain = $domainRepo->findByDomainName($domain->getName());
	    foreach ($domain->getSettings() as $domainSetting) {
		    if($domainSetting->isMain() ){
		    	$frontendLanguage = $domainSetting->getLocale();
			    break;
		    }
	    }
	    if( $frontendLanguage === Locale::LOCALE_ALL || $frontendLanguage === Locale::LOCALE_ANY ){
		    $frontendLanguage = $domain->getSite()->getDefaultLocale();
	    }

		$gk = $runtime->getGatekeeper();
        $user = $gk->getGuestSubject();

	    /**
	     * Alternative Sprachversionen werden in der Sitemap.xml ausgegeben, wenn es mehr als eine aktive Sprache gibt.
	     */
        $activatedLanguages = [];
        $deactivatedLanguages = [];
        foreach ( $client->getLocales() as $clientLocale) {
            if ($clientLocale->getStatus()===Status::ENABLED ){
                $activatedLanguages[] = $clientLocale->getLocaleCode();
            }else {
                $deactivatedLanguages[] = $clientLocale->getLocaleCode();
            }
        }
        $nrActiveLanguages = count($activatedLanguages);

	    ob_start();
        echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
	    echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"'.( $nrActiveLanguages > 1 ? ' xmlns:xhtml="http://www.w3.org/1999/xhtml"' : '') .'>';

        $mailTopic = false;
        if( isset($modulesConf['mail']['setup']['mailnav'][$clientId]) && $modulesConf['mail']['setup']['mailnav'][$clientId]!=''){
            $mailTopic = $modulesConf['mail']['setup']['mailnav'][$clientId];
        }

		$siteStructureCache = $navigation->loadSiteStructureForClientIdAndLanguage($clientId, $frontendLanguage);
		$flatSiteStructure = $siteStructureCache[Navigation::STRUCTURE_CACHE_FLAT];
        foreach ($flatSiteStructure as $elem){
            $languages = isset($elem['element']['status']['languages']) && is_array($elem['element']['status']['languages']) ? $elem['element']['status']['languages'] : [];
			if (tyCheckAccessTopic( $elem["element"]["topic"], "frontend", "show", $user ) &&
                (!isset($elem['element']['status']['from']) || !$elem['element']['status']['from'] || $elem['element']['status']['from']<time()) &&
                !isset($elem['element']['status']['deactivated']) &&
                (!$mailTopic || !in_array($mailTopic,tyGetTopicNaviPathForTopic($elem["element"]["topic"])) ) &&
                $elem['element']['template'] != "_tyExtURL" &&
                $elem['element']['template'] != "_tyInternTOPIC" &&
				in_array($frontendLanguage, $languages)
            ) {
                $navSettings = tyNavSettings::getSettingForTopicRecurse( $elem["element"]["topic"], $frontendLanguage );
                if( !isset($navSettings["index"]) || $navSettings["index"] ){
                    //Haupt-URL setzen
	                $uri = $navigation->getUriForTopicAndLocale($elem['element']['topic'], $frontendLanguage, $frontendLanguage, $clientId);
                    if( null !== $uri ) {
                        echo "\n<url>";
                        echo "<loc>".$uri->toString()."</loc>";
                        if( isset($navSettings["headerInfo"]["meta"]["revisit-after"]["content"]) ){
                            $revisitValue = strtolower( $navSettings["headerInfo"]["meta"]["revisit-after"]["content"] );
                            $revisitNumber = (int)preg_replace('[^0-9]','',$revisitValue);
                            if( strpos($revisitValue, 'day') !== false || strpos($revisitValue, 'tag') !== false ){
                                $revisitNumber *= 24;
                            }else{
                                if( strpos($revisitValue, 'week') !== false || strpos($revisitValue, 'woche') !== false ){
                                    $revisitNumber *= 24*7;
                                }else{
                                    if( strpos($revisitValue, 'month') !== false || strpos($revisitValue, 'monat') !== false ){
                                        $revisitNumber *= 24*30;
                                    }else{
                                        if( strpos($revisitValue, 'year') !== false || strpos($revisitValue, 'jahr') !== false ){
                                            $revisitNumber *= 24*30*12;
                                        }
                                    }
                                }
                            }

                            if( $revisitNumber == 0){
                                // default Value
                                $changeValue = "weekly";
                            }elseif( $revisitNumber <= 2 ){
                                $changeValue = "always";
                            }elseif( $revisitNumber < 24 ){
                                $changeValue = "hourly";
                            }elseif($revisitNumber < 24 * 7){
                                $changeValue = "daily";
                            }elseif($revisitNumber < 24 * 30){
                                $changeValue = "weekly";
                            }elseif($revisitNumber < 24 * 365){
                                $changeValue = "monthly";
                            }else{
                                $changeValue = "Yearly";
                            }

                            echo '<changefreq>' . $changeValue . '</changefreq>';
                        }else{
                            echo '<changefreq>weekly</changefreq>';
                        }
                        if(isset($navSettings["priority"]) && $navSettings["priority"]>=0 && $navSettings["priority"]<=1){
                            echo '<priority>' . $navSettings["priority"] . '</priority>';
                        }
                        /*$last_mod = tyGetLastPageChange($elem['element']['topic']);
                        if(!empty($last_mod) && $last_mod!="1970-01-01"){
                            echo '<lastmod>' . $last_mod . '</lastmod>';
                        }*/

	                    if( $nrActiveLanguages > 1 ) {
							$languageURLs = array();
							$defaultLanguageIndexes = array();

							//myty-Sprachen ermitteln
							foreach($languages AS $i => $lang){
								$locale = $lang;
								$parts = explode('_', $locale);
								if (!array_key_exists($parts[0], $defaultLanguageIndexes) || $parts[0] === $parts[1] ){
									$defaultLanguageIndexes[$parts[0]] = $i;
								}
							}
							//URLs für alle am Navipunkt aktiven Sprachen setzen
							foreach($languages AS $i => $lang){
								if( in_array($lang, $activatedLanguages) ){
									$locale = $lang;
									$uri = $navigation->getUriForTopicAndLocale($elem['element']['topic'], $locale, null, $clientId);
									if($uri){
										$url = $uri->toString();
										if( !in_array($url, $languageURLs) ) {
											$languageURLs[] = $url;
											echo "\n<xhtml:link rel=\"alternate\" hreflang=\"".Locale::toWebLocale($locale)."\" href=\"".$url."\" />";
										}
									}
								}
							}
	                    }
                        echo '</url>';
                    }
                }
			}
        }

        /**
         * Modules sitemaps
         */
        $sitemapFiles = glob(__DIR__.'/../modules/*/sitemap.inc.php',GLOB_NOSORT);
        foreach ($sitemapFiles as $sitemapFile) {
            /** @var SitemapUrl[] $urls */
            $urls = include $sitemapFile; //@phpstan-ignore-line
            if($urls instanceof Iterator){
                echo "\n<!-- Sitemap-File: ".str_replace($rootPath, '', realpath($sitemapFile))." -->";
                foreach ($urls as $url) {
                    if($url !== null) {
                        echo "\n".(is_object($url) ? $url->__toString() : (string)$url);
                    }
                }
                unset($url);
            }
        }

        if( isset($modulesConf['nav']['scripts']['sitemap']) && $modulesConf['nav']['scripts']['sitemap'] != '' && is_file($GLOBALS['documentRoot'] . $modulesConf['nav']['scripts']['sitemap']) ) {
            include($GLOBALS['documentRoot'] . $modulesConf['nav']['scripts']['sitemap']);
        }

        echo '</urlset>';

        $contents = ob_get_contents();
        ob_end_clean();
		if (file_exists($cacheDir)===false) {
            FileUtils::mkdir($cacheDir);
        }
        file_put_contents($cachFile, $contents);

        echo $contents;
    }

} catch (Exception $e) {
    trigger_error($e->getMessage());
}
