<?php


namespace App\Service;


use App\Entity\Document;
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Yaml\Yaml;

class DocumentResolver
{
    private $base;

    /**
     * DocumentResolver constructor.
     *
     * @param \App\Service\KeyLighterVersioner $versioner
     */
    public function __construct(KeyLighterVersioner $versioner)
    {
        $this->base = $versioner->getCurrentDir();
    }

    public function fetch($path)
    {
        $path = $this->buildPath($path);

        $finder = new Finder();
        $finder->name("*.md");

        foreach ($finder->files()->in($path)->getIterator() as $file) {
            $document = $this->getDocument($file->getPathname(), true);

            $metadata = array_merge([
                "title"    => str_replace('-', ' ', $file->getBasename('.md')),
                "category" => basename($file->getPath()),
                "path"     => str_replace(['.md', DIRECTORY_SEPARATOR], [null, '/'], substr($file->getPathname(), strlen($path)+1))
            ], $document->getMetadata());
            $document->setMetadata($metadata);

            yield $file->getFilename() => $document;
        }
    }

    public function getDocument($path, $absolute = false)
    {
        $path = $absolute ? $path : $this->buildPath(trim($path, '/').'.md');

        if (!file_exists($path)) {
            throw new FileNotFoundException("File '$path' was not found.");
        }

        list($content, $meta) = $this->split(file_get_contents($path));
        return new Document($content, $meta);
    }

    private function split(string $content): array
    {
        if(!preg_match('/^-{3,}\h*\R(?P<metadata>.*?)\R-{3,}\h*\R/sm', $content, $matches)) {
            return [ $content,  [] ];
        }

        $metadata = $matches['metadata'];
        return [ trim(substr($content, strlen($matches[0]))), Yaml::parse($metadata) ];
    }

    private function buildPath($path)
    {
        return realpath($this->base.DIRECTORY_SEPARATOR.$path);
    }
}