{#-
Safe Template Macros - Hugo-style error boundaries and safe rendering

These macros provide error isolation and graceful fallbacks for template rendering.
All templates should use these macros to prevent silent failures.
-#}

{#-
Hugo-style error boundary macro

CRITICAL: Whitespace control for clean markdown output
- Strips ALL leading/trailing whitespace from content
- Preserves internal blank lines (needed for markdown structure)
- Adds newline after content so root layout spacing works correctly
- Root layout controls spacing between major sections (blank lines between safe_section calls)
- Partials control spacing between their own internal elements (headings, rubrics, code blocks)
-#}
{% macro safe_section(section_name, show_errors=true) %}
{%- if caller -%}
{%- set content = caller() -%}
{%- if content and content.strip() -%}
{%- set prepared = content.lstrip() -%}
{{- prepared.rstrip() ~ '\n\n' }}
{%- endif -%}
{%- endif -%}
{% endmacro %}

{#- Safe rendering with item-level fallbacks -#}
{% macro safe_render(item_type, item, show_errors=true) %}
{%- if caller and item -%}
{%- set current_item = item -%}
{{- caller() -}}
{%- endif -%}
{% endmacro %}

{#- Safe variable access with defaults -#}
{% macro safe_var(obj, attr, default="-") %}
{%- if obj and attr in obj -%}
{{ obj[attr] }}
{%- else -%}
{{ default }}
{%- endif -%}
{% endmacro %}

{#- Safe attribute access for objects -#}
{% macro safe_attr(obj, attr, default="-") %}
{%- if obj and obj[attr] is defined -%}
{{ obj[attr] }}
{%- else -%}
{{ default }}
{%- endif -%}
{% endmacro %}

{#- Safe list access with bounds checking -#}
{% macro safe_list_item(list_obj, index, default="") %}
{%- if list_obj and list_obj|length > index -%}
{{ list_obj[index] }}
{%- else -%}
{{ default }}
{%- endif -%}
{% endmacro %}

{#- Conditional rendering with safe checks -#}
{% macro if_exists(obj, attr) %}
{% if caller and obj and hasattr(obj, attr) and obj[attr] %}
{{ caller() }}
{% endif %}
{% endmacro %}

{#- Safe iteration with empty state handling -#}
{% macro safe_for(items, empty_message="*No items found.*") %}
{% if items and items|length > 0 %}
{% if caller %}
{% for current_item in items %}
{{ caller(current_item) }}
{% endfor %}
{% endif %}
{% else %}
{{ empty_message }}
{% endif %}
{% endmacro %}

{#- Debug information macro (only shows in debug mode) -#}
{% macro debug_info(label, data) %}
{#- Debug output disabled in macros to avoid context issues -#}
{#- Use direct config access in templates instead -#}
{% endmacro %}

{#-
Spacing Shell Macros - Consistent spacing wrapper pattern

RECOMMENDED: Use shells for major structural elements only (sections, subsections, rubrics).
For simple content (descriptions, inline text), use manual spacing with consistent patterns.

Shells provide:
- Guaranteed spacing (blank lines before/after)
- Self-documenting component types
- Centralized spacing logic

Use shells for:
- section_shell: Major sections (## Classes, ## Functions)
- subsection_shell: Subsections (### `name`)
- rubric_shell: Rubrics (:::{rubric})

Manual spacing for:
- Descriptions/text content (add blank line after if followed by component)
- Code blocks (add blank line before/after)
- Tables (already handled by parameter_table macro)

Example:
  {% call section_shell() %}
  ## Classes
  {% endcall %}

  {% call subsection_shell() %}
  ### `Community`
  {% endcall %}

  {{ element.description }}

  :::{info}
  This is a dataclass.
  :::
-#}

{#- Major section shell (## Classes, ## Functions) -#}
{% macro section_shell() %}
{%- if caller -%}
{%- set content = caller() -%}
{%- if content and content.strip() -%}
{%- set trimmed = content.strip() -%}
{{- '\n\n' ~ trimmed ~ '\n\n' }}
{%- endif -%}
{%- endif -%}
{% endmacro %}

{#- Subsection shell (### `name`) -#}
{% macro subsection_shell() %}
{%- if caller -%}
{%- set content = caller() -%}
{%- if content and content.strip() -%}
{%- set trimmed = content.strip() -%}
{{- '\n\n' ~ trimmed ~ '\n\n' }}
{%- endif -%}
{%- endif -%}
{% endmacro %}

{#- Rubric shell (:::{rubric}) -#}
{% macro rubric_shell() %}
{%- if caller -%}
{%- set content = caller() -%}
{%- if content and content.strip() -%}
{%- set trimmed = content.strip() -%}
{{- '\n\n' ~ trimmed ~ '\n\n' }}
{%- endif -%}
{%- endif -%}
{% endmacro %}

{#-
Autodoc Configuration Helper Macros

These macros handle the complex logic for determining autodoc configuration
from either autodoc_config (available during markdown generation) or
config.autodoc (available during site build rendering).
-#}

{#- Get autodoc config with fallback logic -#}
{% macro get_autodoc_config() %}
{%- set autodoc_cfg = {} -%}
{%- if autodoc_config is defined -%}
{%- set autodoc_cfg = autodoc_config -%}
{%- elif config is defined and 'autodoc' in config -%}
{%- set autodoc_cfg = config['autodoc'] -%}
{%- endif -%}
{{- autodoc_cfg -}}
{% endmacro %}

{#- Generate title for autodoc element -#}
{% macro autodoc_title(element) %}
{%- set autodoc_cfg = {} -%}
{%- if autodoc_config is defined -%}
{%- set autodoc_cfg = autodoc_config -%}
{%- elif config is defined and 'autodoc' in config -%}
{%- set autodoc_cfg = config['autodoc'] -%}
{%- endif -%}

{%- if element -%}
    {%- set is_root_module = element.element_type == 'module' and (not element.qualified_name or '.' not in element.qualified_name) -%}
    {%- set is_root_cli = element.element_type == 'command-group' and (not element.qualified_name or '.' not in element.qualified_name) -%}

    {%- if is_root_module -%}
        {%- if 'python' in autodoc_cfg and 'display_name' in autodoc_cfg['python'] -%}
            {{- autodoc_cfg['python']['display_name'] -}}
        {%- elif element.name and element.name|trim -%}
            {{- element.name }} API
        {%- else -%}
            API Reference
        {%- endif -%}
    {%- elif is_root_cli -%}
        {%- if 'cli' in autodoc_cfg and 'display_name' in autodoc_cfg['cli'] -%}
            {{- autodoc_cfg['cli']['display_name'] -}}
        {%- elif element.name and element.name|trim -%}
            {{- element.name }} CLI
        {%- else -%}
            CLI Reference
        {%- endif -%}
    {%- elif element.name and element.name|trim -%}
        {{- element.name -}}
    {%- elif element.element_type == 'module' -%}
        {%- set root_pkg_name = '' -%}
        {%- if element.qualified_name and element.qualified_name|trim -%}
            {%- set root_pkg_name = element.qualified_name.split('.')[0] -%}
        {%- elif element.source_file -%}
            {%- set root_pkg_name = element.source_file.parent.name -%}
        {%- endif -%}
        {%- if root_pkg_name -%}
            {{- root_pkg_name -}}
        {%- else -%}
            API
        {%- endif -%}
    {%- else -%}
        Documentation
    {%- endif -%}
{%- else -%}
    Documentation
{%- endif -%}
{% endmacro %}

{#- Generate description for autodoc element -#}
{% macro autodoc_description(element) %}
{%- set autodoc_cfg = {} -%}
{%- if autodoc_config is defined -%}
{%- set autodoc_cfg = autodoc_config -%}
{%- elif config is defined and 'autodoc' in config -%}
{%- set autodoc_cfg = config['autodoc'] -%}
{%- endif -%}
{%- if element.description -%}
{{- element.description | safe_description -}}
{%- elif element and element.element_type == 'module' -%}
{%- set pkg_name = '' -%}
{%- if element.name and element.name|trim -%}
{%- set pkg_name = element.name -%}
{%- elif element.qualified_name and element.qualified_name|trim -%}
{%- set pkg_name = element.qualified_name.split('.')[0] -%}
{%- elif element.source_file -%}
{%- set pkg_name = element.source_file.parent.name -%}
{%- endif -%}
{%- if pkg_name -%}
{{- pkg_name }} package
{%- else -%}
{%- if 'default_description' in autodoc_cfg -%}
{{- autodoc_cfg['default_description'] -}}
{%- else -%}
Documentation
{%- endif -%}
{%- endif -%}
{%- elif 'default_description' in autodoc_cfg -%}
{{- autodoc_cfg['default_description'] -}}
{%- else -%}
Documentation
{%- endif -%}
{% endmacro %}
