<?php

namespace Apexl\Io\Template\Services;

use Arrayy\Type\StringCollection;
use Mustache\Exception\UnknownTemplateException;
use Mustache\Loader;

final readonly class MultipleFilesystemLoader implements Loader
{
    private StringCollection $directories;
    private StringCollection $templateCache;

    public function __construct(private string $extension = '.mustache')
    {
        $this->directories = new StringCollection();
        $this->templateCache = new StringCollection();
    }

    public function addDirectory(string $directory): void
    {
        $this->directories->add(realpath($directory));
    }

    public function load($name): string
    {
        if (!$this->templateCache->has($name)) {
            $this->templateCache->set($name, $this->loadFile($name));
        }

        return $this->templateCache->get($name);
    }

    protected function loadFile(string $name): string
    {
        $fileName = $this->getFileName($name);

        if (!file_exists($fileName)) {
            throw new UnknownTemplateException($name);
        }

        return file_get_contents($fileName);
    }

    protected function getFileName(string $name): string
    {

        $fileName = $name;
        if (substr($fileName, 0 - strlen($this->extension)) !== $this->extension) {
            $fileName .= $this->extension;
        }

        foreach ($this->directories as $directory) {
            $filePath = sprintf('%s/%s', $directory, $fileName);

            if (file_exists($filePath)) {
                return realpath($filePath);
            }
        }

        throw new UnknownTemplateException($name);
    }
}
