<?php

/**
 * Created by PhpStorm.
 * User: ondra
 * Date: 19.10.17
 * Time: 11:16.
 */

namespace KupShop\ContentBundle\Controller;

use KupShop\ContentBundle\Exception\UnknownSitemapTypeException;
use KupShop\ContentBundle\Util\SitemapLocator;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Util\CachingStreamedResponse;
use KupShop\KupShopBundle\Util\Contexts;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Router;

class SitemapController extends AbstractController
{
    /**
     * @Route("/sitemap.xml", name="kupshop_content_sitemap")
     */
    public function sitemapIndexAction(SitemapLocator $sitemapLocator): Response
    {
        $writer = new \XMLWriter();
        $writer->openMemory();

        $writer->startDocument('1.0', 'UTF-8');

        $writer->startElement('sitemapindex');
        $writer->writeAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');

        // sitemap parts
        foreach ($this->getSitemaps($sitemapLocator) as $loc) {
            $writer->startElement('sitemap');
            $writer->writeElement('loc', $loc);
            $writer->endElement();
        }

        $writer->endElement();

        $response = new Response($writer->outputMemory(true));
        $response->headers->set('Content-type', 'application/xml');
        $response->headers->set('Content-type', 'text/xml; charset=utf-8');

        return $response;
    }

    /**
     * @Route("/{sequence}/sitemap_{type}.xml", name="kupshop_content_sitemap_sitemaptypesequence")
     * @Route("/sitemap_{type}.xml", name="kupshop_content_sitemap_sitemaptype")
     */
    public function sitemapTypeAction(Request $request, SitemapLocator $sitemapLocator, string $type, ?string $sequence = null): Response
    {
        try {
            $sitemap = $sitemapLocator->getSitemap($type);
        } catch (UnknownSitemapTypeException $e) {
            throw new NotFoundHttpException($type);
        }

        $response = new CachingStreamedResponse();
        $response->headers->set('Content-type', 'application/xml');
        $response->headers->set('Content-type', 'text/xml; charset=utf-8');

        $languageContext = Contexts::get(LanguageContext::class);

        $cacheName = 'sitemap_'.$type;
        if (findModule(\Modules::TRANSLATIONS)) {
            $cacheName = 'sitemap_'.$type.'_'.$languageContext->getActiveId();
        }

        if (!empty($sequence)) {
            $sitemap::setSequence($sequence);
            $cacheName = $cacheName.'_'.$sequence;
        }

        $response->setCacheName($cacheName);
        $response->setTtl(43200);
        $response->setSkipCache($request->get('skip_cache', false));

        $response->setCallback(function () use ($sitemap) {
            $sitemap->render();
        });

        $response->initialize();

        return $response;
    }

    public function getSitemaps(SitemapLocator $sitemapLocator): \Generator
    {
        foreach ($sitemapLocator->getTypes() as $type) {
            try {
                $sitemap = $sitemapLocator->getSitemap($type);
            } catch (UnknownSitemapTypeException $e) {
                throw new NotFoundHttpException($type);
            }

            if ($sitemap->hasSequences()) {
                $countSequences = $sitemap->getCountSequences();
                for ($i = 1; $i <= $countSequences; $i++) {
                    yield path('kupshop_content_sitemap_sitemaptypesequence', ['type' => $type, 'sequence' => $i], Router::ABSOLUTE_URL);
                }
            } else {
                yield path('kupshop_content_sitemap_sitemaptype', ['type' => $type], Router::ABSOLUTE_URL);
            }
        }
    }
}
