<?php
namespace Newland\NeosCommon\Sitemap;

use Neos\ContentRepository\Domain\Model\NodeInterface;
use Neos\Eel\ProtectedContextAwareInterface;
use Neos\Flow\ObjectManagement\ObjectManager;
use Neos\Flow\Annotations as Flow;

/**
 * @Flow\Scope("singleton")
 */
class SitemapHelper implements ProtectedContextAwareInterface
{

    /**
     * @var ObjectManager
     * @Flow\Inject()
     */
    protected $objectManager;

    /**
     * Renders a sitemap from the given provider.
     * The first argument must be a fully qualified namespace of a class that provides the
     * sitemap data. All sitemap providers must implement the {@link SitemapProvider} interface.
     *
     * @example
     * phpcs:disable
     * prototype(Neos.Seo:XmlSitemap.UrlList) {
     *      \@process.addPoiDetail = ${value + Newland.NeosCommon.Sitemap.render('Newland\\Toubiz\\Poi\\Neos\\Sitemap\\PoiDetailSitemapProvider', site)}
     * }
     * phpcs:enable
     *
     * @param string $providerName
     * @param NodeInterface $site
     * @return string
     */
    public function render(string $providerName, NodeInterface $site)
    {
        return implode(array_map(
            function (SitemapUrl $item) {
                return $item->toXml();
            },
            $this->initializeProvider($providerName)->getPages($site)
        ));
    }

    /**
     * @param string $methodName
     * @return boolean
     */
    public function allowsCallOfMethod($methodName)
    {
        return $methodName === 'render';
    }

    private function initializeProvider(string $providerName): SitemapProvider
    {
        $provider = $this->objectManager->get($providerName);
        if (!($provider instanceof SitemapProvider)) {
            throw new \InvalidArgumentException(
                'The given sitemap provider must implement ' . SitemapProvider::class
            );
        }
        return $provider;
    }
}
