<?php

namespace App\Markdown\Parser;

use Knp\Bundle\MarkdownBundle\Parser\MarkdownParser;

/**
 * class Post.
 *
 * @author Simon Vieille <simon@deblan.fr>
 */
class Post extends MarkdownParser
{
    /**
     * {@inheritdoc}
     */
    //protected $id_class_attr_catch_re = '\{((?'.'>[ ]*[#.a-z][-_:a-zA-Z0-9="\'\/\*-]+){1,})[ ]*\}';
    protected $id_class_attr_catch_re = '\{([^\}]+)\}';

    /**
     * {@inheritdoc}
     */
    public function transformMarkdown($text)
    {
        $html = parent::transformMarkdown($text);

        return str_replace(' role="doc-endnote"', '', $html);
    }

    /**
     * {@inheritdoc}
     */
    protected function doExtraAttributes($tag_name, $attr, $defaultIdValue = null, $classes = [])
    {
        if (empty($attr) && !$defaultIdValue && empty($classes)) {
            return '';
        }

        // Split on components
        preg_match_all('/[#.a-z][-_:a-zA-Z0-9]+/', $attr, $matches);
        $elements = $matches[0];

        // Handle classes and IDs (only first ID taken into account)
        $attributes = [];
        $id = false;
        foreach ($elements as $element) {
            if ('.' == $element[0]) {
                $classes[] = substr($element, 1);
            } elseif ('#' == $element[0]) {
                if (false === $id) {
                    $id = substr($element, 1);
                }
            }
        }

        preg_match_all('/[#.]{0}([a-z-]+)=([:a-zA-Z0-9]+)/', $attr, $matches, PREG_SET_ORDER);

        foreach ($matches as $match) {
            $attributes[] = sprintf('%s="%s"', $match[1], htmlspecialchars($match[2]));
        }

        preg_match_all('/[#.]{0}([a-z-]+)=(["\']{1})(.+)\2/isUu', $attr, $matches, PREG_SET_ORDER);

        foreach ($matches as $match) {
            $attributes[] = sprintf('%s="%s"', $match[1], htmlspecialchars($match[3]));
        }

        if (!$id) {
            $id = $defaultIdValue;
        }

        // Compose attributes as string
        $attr_str = '';
        if (!empty($id)) {
            $attr_str .= ' id="'.$this->encodeAttribute($id).'"';
        }
        if (!empty($classes)) {
            $attr_str .= ' class="'.implode(' ', $classes).'"';
        }
        if (!$this->no_markup && !empty($attributes)) {
            $attr_str .= ' '.implode(' ', $attributes);
        }

        return $attr_str;
    }

    protected function _doFencedCodeBlocks_callback($matches)
    {
        $classname = &$matches[2];
        $attrs = &$matches[3];
        $codeblock = $matches[4];

        if ($this->code_block_content_func) {
            $codeblock = call_user_func($this->code_block_content_func, $codeblock, $classname);
        } else {
            $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
        }

        $codeblock = str_replace(
            ['&lt;mark&gt;', '&lt;/mark&gt;'],
            ['<mark>', '</mark>'],
            $codeblock
        );

        $codeblock = preg_replace_callback('/^\n+/',
            [$this, '_doFencedCodeBlocks_newlines'], $codeblock);

        $classes = [];
        if ('' != $classname) {
            if ('.' == $classname[0]) {
                $classname = substr($classname, 1);
            }
            $classes[] = $this->code_class_prefix.$classname;
        }
        $attr_str = $this->doExtraAttributes($this->code_attr_on_pre ? 'pre' : 'code', $attrs, null, $classes);
        $pre_attr_str = $this->code_attr_on_pre ? $attr_str : '';
        $code_attr_str = $this->code_attr_on_pre ? '' : $attr_str;
        $codeblock = "<pre{$pre_attr_str}><code{$code_attr_str}>{$codeblock}</code></pre>";

        return "\n\n".$this->hashBlock($codeblock)."\n\n";
    }
}
