{% 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_community(left, comm, right, peer_as=None, dyn_val=None, is_delete=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 }}
{%			else %}
# Warning: must skip {{ comm.std }} because peer_as > 65535 ({{ peer_as }})
{%			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 }}
{%			else %}
# Warning: must skip {{ comm.std }} because dyn_val > 65535 ({{ dyn_val }})
{%			endif %}
{%		else %}
{{ left }} community {{ delete }}{{ comm.std }}{{ right_val }}
{%		endif %}
{%	endif %}
{%      if comm.ext %}
{%              if "peer_as" in comm.ext %}
{%			if peer_as == "*" %}
# Warning: {{ comm.ext }} ext comm skipped: can't delete ext comms using wildcard
{%			else %}
{{ left }} ext-community {{ delete }}{{ comm.ext|convert_ext_comm|replace("peer_as", peer_as) }}{{ right_val }}
{%			endif %}
{%		else %}
{%			if "dyn_val" in comm.ext and dyn_val == "*" %}
# Warning: {{ comm.ext }} ext comm skipped: can't delete ext comms using wildcard
{%			else %}
{{ left }} ext-community {{ delete }}{{ comm.ext|convert_ext_comm|replace("dyn_val", dyn_val) }}{{ right_val }}
{%			endif %}
{%		endif %}
{%	endif %}
{%      if comm.lrg and "6.1"|target_version_ge %}
{%              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 %}
{%	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) %}
{{ write_community(left ~ " set", comm, "", None, dyn_val) }}
{% endmacro %}

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

{% macro write_prepending_comm(comm, asn, rtt_thresholds) %}
{%	if comm|community_is_set %}
{%		if comm.std %}
{%			if not asn or asn <= 65535 %}
{{-			" community delete " ~ comm.std|replace("peer_as", asn)|replace("dyn_val", "*") -}}
{%			endif %}
{%		endif %}
{%		if comm.ext %}
{%			if "dyn_val" in comm.ext %}
{%				for threshold_val in rtt_thresholds %}
{{-					" ext-community delete " ~ comm.ext|convert_ext_comm|replace("peer_as", asn)|replace("dyn_val", threshold_val) -}}
{%				endfor %}
{%			else %}
{{-				" ext-community delete " ~ comm.ext|convert_ext_comm|replace("peer_as", asn) -}}
{%			endif %}
{%		endif %}
{%		if comm.lrg and "6.1"|target_version_ge %}
{{-			" large-community delete " ~ comm.lrg|replace("peer_as", asn)|replace("dyn_val", "*") -}}
{%		endif %}
{%	endif %}
{% endmacro %}

{% macro list_prepending_comms(comms, asn, rtt_thresholds) %}
{% for comm_name in comms|sort %}
{%	if comm_name.startswith("prepend_") %}
{%		set comm = comms[comm_name] %}
{%		if comm|community_is_set %}
{{-			write_prepending_comm(comm, asn, rtt_thresholds) -}}
{%		endif %}
{%	endif %}
{% endfor %}
{% endmacro %}

{% macro remove_prepending_comms(left, if_comm, comms, asn, rtt_thresholds, if_comm_dyn_val=None) %}
{{ match_communities(left, if_comm, "set { " ~ list_prepending_comms(comms, asn, rtt_thresholds) ~ " }", peer_as=asn, dyn_val=if_comm_dyn_val) }}
{% endmacro %}
