<?php declare(strict_types=1);

namespace Newland\Toubiz\Map\Neos\Service;

use Neos\ContentRepository\Domain\Model\NodeInterface;
use Neos\Fusion\View\FusionView;
use Neos\Flow\Annotations as Flow;
use Newland\NeosCommon\Service\ControllerContextFactory;

class FusionSnippetRenderer
{
    /**
     * @var ControllerContextFactory
     * @Flow\Inject()
     */
    protected $controllerContextFactory;

    /**
     * Renders a fusion snippet.
     *
     * A fusion snippet is a self-contained piece of fusion code (does not rely on paths declared outside / must include
     * everything it needs manually) that can be rendered from here.
     *
     * All snippets must be located in the directory Resources/Private/Fusion/Snippets.
     *
     * @example
     * // In fusion:
     * include: resource://Newland.NeosCommon/Private/Fusion/Root.fusion
     * lib.newland.toubiz.map.neos {
     *      convertUris = Neos.Neos:ConvertUris
     * }
     *
     * // In php:
     * $this->fusionSnippetRenderer('lib.newland.toubiz.map.neos.convertUris', [ 'value' => $uri ], $node);
     */
    public function renderSnippet(
        string $path,
        array $context,
        NodeInterface $referenceNode,
        string $package = 'Newland.Toubiz.Map.Neos'
    ): string {
        $slashSeparatedPath = str_replace('.', '/', $path);

        $fusion = new FusionView();
        $fusion->setControllerContext($this->controllerContextFactory->initializeFakeControllerContext($referenceNode));
        $fusion->setOption('fusionPathPatterns', [ 'resource://@package/Private/Fusion/Library' ]);
        $fusion->setPackageKey($package);
        $fusion->setFusionPath($slashSeparatedPath);
        $fusion->disableFallbackView();
        $fusion->assign('node', $referenceNode);
        $fusion->assignMultiple($context);

        return $fusion->render();
    }
}
