<?php
namespace intec\regionality\seo\converters;

use intec\core\helpers\StringHelper;
use intec\regionality\seo\Converter;

/**
 * Класс, предназначенный для преобразования robots.txt в исполняемый код.
 * Class RobotsConverter
 * @package intec\regionality\seo\converters
 * @author apocalypsisdimon@gmail.com
 */
class RobotsConverter extends Converter
{
    /** Текстовый макрос домена в пользовательском содержимом. */
    const DOMAIN_MACRO = '{domain}';

    /** PHP-подстановка домена в сгенерированном файле. */
    const DOMAIN_REPLACEMENT = '<?= $domain ?>';

    /**
     * Заменяет текстовый макрос домена на PHP-подстановку в генерируемом файле.
     * @param string $content
     * @return string
     */
    protected function applyDomainMacro($content)
    {
        return StringHelper::replace($content, [
            static::DOMAIN_MACRO => static::DOMAIN_REPLACEMENT
        ]);
    }

    /**
     * Заменяет PHP-подстановку домена на текстовый макрос для редактирования.
     * @param string $content
     * @return string
     */
    protected function revertDomainMacro($content)
    {
        return StringHelper::replace($content, [
            static::DOMAIN_REPLACEMENT => static::DOMAIN_MACRO
        ]);
    }

    /**
     * Возвращает заголовок ответа для robots.
     * @return string
     */
    public function getHeader()
    {
        return <<<'HEADER'
<?php header('Content-Type: text/plain'); ?>
HEADER;
    }

    /**
     * Возвращает автогенерируемый префикс файла (пролог и заголовок ответа).
     * @return string
     */
    public function getGeneratedPrefix()
    {
        return $this->getPrologue().$this->getHeader();
    }

    /**
     * Проверяет, что содержимое файла начинается с автогенерируемого префикса.
     * @param string|null $content
     * @return boolean
     */
    public function hasGeneratedPrefix($content)
    {
        if ($content === null || $content === '')
            return false;

        $prefix = $this->normalizeForCompare($this->getGeneratedPrefix());
        $content = $this->normalizeForCompare($content);

        return StringHelper::startsWith($content, $prefix);
    }

    /**
     * Извлекает пользовательское тело файла без прologa и заголовка ответа.
     * @param string|null $content
     * @return string
     */
    public function extractBody($content)
    {
        if ($content === null || $content === '')
            return '';

        $prefix = $this->normalizeForCompare($this->getGeneratedPrefix());
        $content = $this->normalizeForCompare($content);

        if (!StringHelper::startsWith($content, $prefix))
            return '';

        $body = StringHelper::cut($content, StringHelper::length($prefix));

        return $this->revertDomainMacro($body);
    }

    /**
     * Удаляет PHP-теги из пользовательского содержимого.
     * @param string|null $content
     * @return string
     */
    public function sanitizeBody($content)
    {
        if ($content === null || $content === '')
            return '';

        $content = (string)$content;
        $content = preg_replace('/<\?(?:php|=)?.*?\?>/is', '', $content);

        return str_ireplace(['<?php', '<?=', '<?'], '', $content);
    }

    /**
     * @inheritdoc
     */
    public function convert($content)
    {
        $content = $this->sanitizeBody($content);
        $content = $this->applyDomainMacro($content);

        $result = $this->getHeader().$content;

        return $this->wrap($result);
    }
}