{% macro write_prefix_list_entry(entry) %}
{{		entry.prefix }}/{{ entry.length -}}
{%-		if not entry.exact -%}
{{ " prefixlen " }}
{%-			if entry.ge -%}
{%-				set prefixlen_start = entry.ge %}
{%-			else -%}
{%-				set prefixlen_start = entry.length %}
{%-			endif -%}
{%-			if entry.le -%}
{%-				set prefixlen_end = entry.le %}
{%- 			else -%}
{%-				set prefixlen_end = entry.max_length %}
{%- 			endif -%}
{%-			if prefixlen_start != prefixlen_end %}
{{				prefixlen_start ~ " - " ~ prefixlen_end }}
{%-			else %}
{{				"= " ~ prefixlen_start }}
{%-			endif %}
{%-		endif -%}
{% endmacro %}

{% macro write_prefix_list(prefix_list, ip_ver=None) %}
{% for entry in prefix_list if not ip_ver or entry.prefix|ipaddr_ver == ip_ver %}
{{	write_prefix_list_entry(entry) -}}
{%	if not loop.last %}{{ ", " }}{% endif %}
{% endfor %}
{% endmacro %}

{% macro write_prefixset_list(prefix_list, ip_ver=None) %}
{% for entry in prefix_list if not ip_ver or entry.prefix|ipaddr_ver == ip_ver %}
{{	"    " ~ write_prefix_list_entry(entry) }}
{% endfor %}
{% endmacro %}

{%- macro write_community(left, comm, right, peer_as=None, dyn_val=None, is_delete=False, dyn_val_is_peer_as=False) -%}
{%- if is_delete -%}
{%- set delete = "delete " -%}
{%- else -%}
{%- set delete = "" -%}
{%- endif -%}
{%- if right -%}
{%- set right_val = " " ~ right -%}
{%- else -%}
{%- set right_val = "" -%}
{%- endif -%}
{%- if comm|community_is_set -%}
{%-     if comm.std -%}
{%-         if "peer_as" in comm.std -%}
{%-             if peer_as == "*" or peer_as <= 65535 -%}
{{ left }} community {{ delete }}{{ comm.std|replace("peer_as", peer_as) }}{{ right_val }}
{%-             elif peer_as and peer_as > 65535 and peer_as in asn3216_map -%}
# {{ asn3216_map[peer_as] }} is the 16bit_mapped_asn for {{ peer_as }}
{{ left }} community {{ delete }}{{ comm.std|replace("peer_as", asn3216_map[peer_as]) }}{{ right_val }}
{%-             else -%}
# Warning: must skip {{ comm.std }} because peer_as ({{ peer_as }}) > 65535 and
# there isn't any 16bit mapped ASN for it.
{%-             endif -%}
{%-         elif "dyn_val" in comm.std -%}
{%-             if dyn_val == "*" or dyn_val <= 65535 -%}
{{ left }} community {{ delete }}{{ comm.std|replace("dyn_val", dyn_val) }}{{ right_val }}
{%-             elif dyn_val and dyn_val > 65535 and dyn_val in asn3216_map and dyn_val_is_peer_as -%}
# {{ asn3216_map[dyn_val] }} is the 16bit_mapped_asn for {{ dyn_val }}
{{ left }} community {{ delete }}{{ comm.std|replace("dyn_val", asn3216_map[dyn_val]) }}{{ right_val }}
{%-             else -%}
# Warning: must skip {{ comm.std }} because dyn_val ({{ dyn_val }}) > 65535 and
# there isn't any 16bit mapped ASN for it.
{%-             endif -%}
{%-         else -%}
{{ left }} community {{ delete }}{{ comm.std }}{{ right_val }}
{%-         endif -%}
{%-         if left -%}{{ "\n" }}{%- endif -%}
{%-     endif -%}
{%-     if comm.ext -%}
{%-         if "peer_as" in comm.ext -%}
{%-             if comm.ext.split(":")[1]|int <= 65535 or peer_as == "*" or peer_as|int <= 65535 -%}
{{ left }} ext-community {{ delete }}{{ comm.ext|convert_ext_comm|replace("peer_as", peer_as) }}{{ right_val }}
{%-             else -%}
# Warning: must skip {{ comm.ext }} because peer_as > 65535 ({{ peer_as }}) and also {{ comm.ext.split(":")[1] }} is a 32bit number
{%-             endif -%}
{%-         else -%}
{{ left }} ext-community {{ delete }}{{ comm.ext|convert_ext_comm|replace("dyn_val", dyn_val) }}{{ right_val }}
{%-         endif -%}
{%-         if left -%}{{ "\n" }}{%- endif -%}
{%-     endif -%}
{%-     if comm.lrg -%}
{%-         if "peer_as" in comm.lrg -%}
{{ left }} large-community {{ delete }}{{ comm.lrg|replace("peer_as", peer_as) }}{{ right_val }}
{%-         else -%}
{{ left }} large-community {{ delete }}{{ comm.lrg|replace("dyn_val", dyn_val) }}{{ right_val }}
{%-         endif -%}
{%-         if left -%}{{ "\n" }}{%- endif -%}
{%-     endif -%}
{%- endif -%}
{%- endmacro -%}


{% macro match_communities(left, comm, right, peer_as=None, dyn_val=None) %}
{{ write_community(left, comm, right, peer_as, dyn_val) }}
{% endmacro %}

{% macro add_communities(left, comm, dyn_val=None, dyn_val_is_peer_as=False) %}
{{ write_community(left ~ " set", comm, "", None, dyn_val, dyn_val_is_peer_as=dyn_val_is_peer_as) -}}
{% endmacro %}

{%- macro ins_communities(comm, dyn_val=None) -%}
{{- write_community("", comm, "", None, dyn_val) -}}
{%- endmacro -%}

{% macro del_communities(left, comm, replace_peer_as=False, replace_dyn_val=None, dyn_val_is_peer_as=False) %}
{% if replace_peer_as %}
{%	set peer_as = "*" %}
{% else %}
{%	set peer_as = None %}
{% endif %}
{{ write_community(left ~ " set", comm, "", peer_as, replace_dyn_val, True, dyn_val_is_peer_as=dyn_val_is_peer_as) }}
{% endmacro %}

{% macro delete_prepending_comm(comm, rtt_thresholds) %}
{%	if comm|community_is_set %}
{%		if comm.std %}
{{			"	community delete " ~ comm.std|replace("peer_as", "*")|replace("dyn_val", "*") }}
{%		endif %}
{%		if comm.ext %}
{{			"	ext-community delete " ~ comm.ext|convert_ext_comm|replace("peer_as", "*")|replace("dyn_val", "*") }}
{%		endif %}
{%		if comm.lrg %}
{{			"	large-community delete " ~ comm.lrg|replace("peer_as", "*")|replace("dyn_val", "*") }}
{%		endif %}
{%	endif %}
{% endmacro %}

{% macro write_roas_action(rpki_roas, action) %}
{%	for roa in rpki_roas if roa.asn != 0 %}
match from group clients source-as {{ roa.asn }} prefix {{ roa.prefix }}
{%-		if roa.length != roa.max_len %}
 prefixlen {{ roa.length }} - {{ roa.max_len }}
{%-		endif %}
 {{ action }}
{%	endfor %}
{% endmacro %}

{% macro write_roa_set(rpki_roas) %}
{%    for roa in rpki_roas %}
    {{ roa.prefix }}
{%-        if roa.length != roa.max_len %}
 maxlen {{ roa.max_len }}
{%-        endif %}
 source-as {{ roa.asn }}
{%-        if "7.2"|target_version_ge and "expires" in roa %}
 expires {{ roa.expires }}
{%-        endif %}

{%    endfor %}
{% endmacro %}
