<?php
/**
 * For the full copyright and license information, please view the
 * docs/licenses/LICENSE.txt file that was distributed with this source code.
 */

namespace PrestaShop\PrestaShop\Core\MailTemplate;

use PrestaShop\PrestaShop\Core\Exception\FileNotFoundException;
use PrestaShop\PrestaShop\Core\Language\LanguageInterface;
use PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutCollectionInterface;
use PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Symfony\Component\Filesystem\Filesystem;

/**
 * Class MailTemplateGenerator iterates through the layouts in the provided theme,
 * it uses the Renderer to display them (with the requested LanguageInterface) and
 * then export them as template files in the specified output folder.
 */
class MailTemplateGenerator
{
    use LoggerAwareTrait;

    /** @var MailTemplateRendererInterface */
    private $renderer;

    /** @var Filesystem */
    private $fileSystem;

    /**
     * @param MailTemplateRendererInterface $renderer
     * @param LoggerInterface|null $logger
     */
    public function __construct(
        MailTemplateRendererInterface $renderer,
        ?LoggerInterface $logger = null
    ) {
        $this->renderer = $renderer;
        $this->logger = null !== $logger ? $logger : new NullLogger();
        $this->fileSystem = new Filesystem();
    }

    /**
     * @param ThemeInterface $theme
     * @param LanguageInterface $language
     * @param string $coreOutputFolder
     * @param string $modulesOutputFolder
     * @param bool $overwriteTemplates [default=false]
     *
     * @throws FileNotFoundException
     */
    public function generateTemplates(
        ThemeInterface $theme,
        LanguageInterface $language,
        $coreOutputFolder,
        $modulesOutputFolder,
        $overwriteTemplates = false
    ) {
        if (!is_dir($coreOutputFolder)) {
            throw new FileNotFoundException(sprintf('Invalid core output folder "%s"', $coreOutputFolder));
        }

        if (!is_dir($modulesOutputFolder)) {
            throw new FileNotFoundException(sprintf('Invalid modules output folder "%s"', $modulesOutputFolder));
        }

        $this->logger->info(sprintf(
            'Exporting mail with theme %s for language %s, Core output folder: %s, Modules output folder: %s',
            $theme->getName(),
            $language->getName(),
            $coreOutputFolder,
            $modulesOutputFolder,
        ));

        /** @var LayoutCollectionInterface $layouts */
        $layouts = $theme->getLayouts();
        /** @var LayoutInterface $layout */
        foreach ($layouts as $layout) {
            if (!empty($layout->getModuleName())) {
                $outputFolder = implode(DIRECTORY_SEPARATOR, [$modulesOutputFolder, $layout->getModuleName(), 'mails', $language->getIsoCode()]);
            } else {
                $outputFolder = implode(DIRECTORY_SEPARATOR, [$coreOutputFolder, $language->getIsoCode()]);
            }

            // Generate HTML template
            $htmlTemplatePath = $this->generateTemplatePath($layout, MailTemplateInterface::HTML_TYPE, $outputFolder);
            if (!$this->fileSystem->exists($htmlTemplatePath) || $overwriteTemplates) {
                $generatedTemplate = $this->renderer->renderHtml($layout, $language);
                $this->fileSystem->dumpFile($htmlTemplatePath, $generatedTemplate);
                $this->logger->debug(sprintf('Generate html template %s at %s', $layout->getName(), $htmlTemplatePath));
            }

            // Generate TXT template
            $txtTemplatePath = $this->generateTemplatePath($layout, MailTemplateInterface::TXT_TYPE, $outputFolder);
            if (!$this->fileSystem->exists($txtTemplatePath) || $overwriteTemplates) {
                $generatedTemplate = $this->renderer->renderTxt($layout, $language);
                $this->fileSystem->dumpFile($txtTemplatePath, $generatedTemplate);
                $this->logger->debug(sprintf('Generate txt template %s at %s', $layout->getName(), $txtTemplatePath));
            }
        }
    }

    /**
     * @param LayoutInterface $layout
     * @param string $templateType
     * @param string $outputFolder
     *
     * @return string
     */
    private function generateTemplatePath(LayoutInterface $layout, $templateType, $outputFolder)
    {
        return implode(DIRECTORY_SEPARATOR, [$outputFolder, $layout->getName()]) . '.' . $templateType;
    }
}
