{#
    A Jinja2 template for rendering stories in tmt's own docs.

    The template is based on a template bundled with tmt as an
    example on template/rst export. The difference is how links
    are rendered: the default template renders just the very basic
    info about idea vs. implemented/verified, this template tries
    to render links related to tmt docs and sources as usable HTTP
    links.
#}

{#
    Render a given example as a `code-block`.

    :param str example: the example to render. May contain syntax
        token to use for highlighting instead of the default ``yaml``.
#}
{% macro render_example(example) %}
    {% set example = example.strip() %}
    {% set syntax = example | regex_search('^# syntax: ([a-z]+)') %}
    {% if syntax %}
        {% set example = '\n'.join(example.splitlines()[1:]) %}
        {% set syntax = syntax[0] %}
    {% else %}
        {% set syntax = 'yaml' %}
    {% endif %}

.. code-block:: {{ syntax }}

   {{ example | indent(width=3, first=False, blank=False) | trim }}
{% endmacro %}

{#
    Convert link relation into a nicely formatted string.

    :param tmt.base.core.Link link: instance.
#}
{% macro printable_relation(link) %}{{ link.relation.replace('relates', 'relates-to').replace('-', ' ').capitalize() }}{% endmacro %}

{#
    Emit a remote link.

    :param tmt.base.core.Link link: link to render.
    :param str label: label of the link.
    :param url: URL to point at.
#}
{% macro _emit_remote_link(link, label, url) %}
* {{ printable_relation(link) }} `{{ label }} <{{ url }}>`_{% if link.note %} ({{ link.note }}){% endif %}
{% endmacro %}

{#
    Emit a link leading to something in tmt upstream repository.

    :param tmt.base.core.Link link: link to render.
#}
{% macro emit_tmt_repo_link(link) %}
{{ _emit_remote_link(link, link.target, link.target | web_git_url(STORY.fmf_id.url, STORY.fmf_id.ref)) }}
{% endmacro %}

{#
    Emit a link leading to tmt plugin sources.

    :param tmt.base.core.Link link: link to render.
#}
{% macro emit_tmt_plugin_link(link) %}
{% set matched = link.target | match('^/tmt/steps/([a-z_]+/[a-z_]+)\\.py$') %}
{#
    A couple of plugins where the file name does not match the "how" name
    used commonly in fmf files/on command line.
#}
{% set plugin_name = matched.group(1) %}
{% if plugin_name == "execute/internal" %}
    {% set plugin_name = "execute/tmt" %}
{% elif plugin_name == "provision/mrack" %}
    {% set plugin_name = "provision/beaker" %}
{% elif plugin_name == "provision/podman" %}
    {% set plugin_name = "provision/container" %}
{% elif plugin_name == "provision/testcloud" %}
    {% set plugin_name = "provision/virtual" %}
{% endif %}
{{ _emit_remote_link(link, plugin_name, link.target | web_git_url(STORY.fmf_id.url, STORY.fmf_id.ref)) }}
{% endmacro %}

{#
    Emit a link leading to fmf object in tmt upstream repository.

    Since a link can point to a root of hierarchy of fmf objects, we
    render all of them, with their names instead of labeling them all
    with ``link.target``.

    We are ignoring stories on purpose: stories are rendered as docs,
    therefore links pointing to stories are rendered as in-doc references
    by the template.

    :param tmt.base.core.Link link: link to render.
#}
{% macro emit_tmt_object_links(link) %}
{% if link.target.startswith('/tests') %}
  {% set objects = STORY.tree.tests(names=["^" + link.target + "(/|$)"]) %}
{% elif link.target.startswith('/plans') %}
  {% set objects = STORY.tree.plans(names=["^" + link.target + "(/|$)"]) %}
{% else %}
  {{ raise_error("Cannot use emit_tmt_object_links for target '" + link.target + "'.") }}
{% endif %}
{% if not objects %}
  {{ raise_error("No test or plan was found for target '" + link.target + "'.") }}
{% endif %}
{% for object in objects %}
{{ _emit_remote_link(link, object.name, object.web_link()) }}
{% endfor %}
{% endmacro %}

{#
    Emit a link leading to tmt's own docs/ directory.

    :param link: tmt.base.core.Link instance.
    :param pattern: used to extract page and fragment from link's target. It
        shall include two capturing groups, representing the page and optional
        fragment.
#}
{% macro emit_docs_link(link) %}
{% set matched = link.target | match('^/docs/(.+?)\\.rst(?:#([a-z\-]+))?$') %}
* {{ printable_relation(link) }} :ref:`{{ matched.group(1) }}{# {% if matched.group(2) %}:{{ matched.group(2).replace('-', ' ') }}{% endif %} #}`
{% endmacro %}

{% if INCLUDE_TITLE %}
{% set depth = STORY.name | regex_findall('/') | length - 1 %}
{% set title_underline = '=~^:-><'[depth] %}
{% if STORY.title and STORY.title != STORY.node.parent.get('title') %}
    {% set title = STORY.title %}
{% else %}
    {% set title = STORY.name | regex_replace('.*/', '') %}
{% endif %}

.. _{{ STORY.name | trim }}:

{{ title | trim }}
{{ title_underline * title | length }}
{% endif %}

{# Summary, story and description #}
{% if STORY.summary and STORY.summary != STORY.node.parent.get('summary') %}
{{ STORY.summary | trim }}
{% endif %}

{% if STORY.story != STORY.node.parent.get('story') %}
*{{ STORY.story | trim }}*
{% endif %}

{# Insert note about unimplemented feature (leaf nodes only) #}
{% if not STORY.node.children and not STORY.implemented %}
.. note:: This is a draft, the story is not implemented yet.
{% endif %}

{% if STORY.description and STORY.description != STORY.node.parent.get('description') %}
{{ STORY.description }}
{% endif %}

{# Examples #}
{% if STORY.example and STORY.example != STORY.node.parent.get('example') %}
    {% for example in STORY.example %}
        {% if example == STORY.example | first %}
**Examples:**
        {% endif %}

{{ render_example(example) }}
    {% endfor %}
{% endif %}

{# Status #}
{% if not STORY.node.children %}
    {% if STORY.status %}
**Status:** {{ STORY.status | listed }}
    {% else %}
**Status:** idea
    {% endif %}
{% endif %}

{# Links #}
{% for link in STORY.link.get() %}
{# Links pointing to docs #}
{% if link.target | match('^/docs/') %}
{{ emit_docs_link(link) }}

{# Links pointing to step core implementation #}
{% elif link.target | match('^/tmt/steps(?:/__init__.py)?$') %}
{{ emit_tmt_repo_link(link) }}

{# Links pointing to step implementations #}
{% elif link.target | match('^/tmt/steps/([a-z_]+)(?:$|(?:/__init__.py))$') %}
{{ emit_tmt_repo_link(link) }}

{# Links pointing to step plugins #}
{% elif link.target | match('^/tmt/steps/([a-z_]+/[a-z_]+)\\.py$') %}
{{ emit_tmt_plugin_link(link) }}

{# Links pointing to other tmt code #}
{% elif link.target.startswith('/tmt') %}
{{ emit_tmt_repo_link(link) }}

{# Links pointing to stories #}
{% elif link.target | match('^/stories') %}
* {{ printable_relation(link) }} :ref:`{{ link.target }}`

{# Links pointing to tests #}
{% elif link.target | match ('^/tests') %}
{{ emit_tmt_object_links(link) }}

{# Links pointing to plans #}
{% elif link.target | match ('^/plans') %}
{{ emit_tmt_object_links(link) }}

{# Links pointing to websites #}
{% elif link.target | match('^https?://') %}
* {{ printable_relation(link) }} `{{ link.target }} <{{ link.target }}>`_

{# Links pointing to anything else #}
{% else %}
* {{ printable_relation(link) }} ``{{ link.target }}``
{% endif %}
{% endfor %}
