{# Macro, put quotation marks around strings that are not ipv4 address #}
{%- macro quote_if_not_ip(var) -%}
{%- set var_split_str = var.split(".") -%}
    {%- if var_split_str|length == 4 -%}
        {%- set var_is_ipaddr = True -%}
        {%- for octet in var_split_str -%}
            {%- if not octet|int in range(255) -%}
                {%- set var_is_ipaddr = False -%}
            {%- endif -%}
        {%- endfor -%}
    {%- endif -%}
    {%- if var_is_ipaddr is defined and var_is_ipaddr == True -%}
{{ var }}
    {%- else -%}
"{{ var }}"
    {%- endif -%}
{%- endmacro -%}

{# Macro, renders nested options for specific key #}
{%- macro render_key(section, key) -%}
{%- if section.get(key) and section.get(key)|length > 0 %}
     {%- for item in section.get(key) %}
        {%- if item.declaration is string %}
{{ key }} {{ item.option }} {{ quote_if_not_ip(item.declaration) }};
        {%- elif item.declaration is sequence %}
{{ key }} {{ item.option }}
            {%- for value in item.declaration -%}
                {%- set space = " " -%}
{{ space }}{{ quote_if_not_ip(value) }}
                {%- if not loop.last -%},{%- endif -%}
            {%- endfor -%}
;
        {%- else %}
{{ key }} {{ item.option }} {{ item.declaration }};
        {%- endif -%}
    {%- endfor -%}
{%- endif -%}
{%- endmacro -%}

{# Macro, renders set of options for global section or for interface section #}
{%- macro render_section(section) -%}
{%- if section.backoff_cutoff is defined %}
backoff-cutoff {{ section.backoff_cutoff|default(15, true) }};
{%- endif -%}

{%- if section.initial_interval is defined %}
initial-interval {{ section.initial_interval|default(10, true) }};
{%- endif -%}

{%- if section.reboot is defined %}
# The reboot statement sets the time that must elapse after the client
# first tries to reacquire its old address before it gives up and tries
# to discover a new address.
reboot {{ section.reboot|default(10, true) }};
{%- endif -%}

{%- if section.retry is defined %}
retry {{ section.retry|default(60, true) }};
{%- endif -%}

{%- if section.select_timeout is defined %}
# The select-timeout is the time after the client sends its first lease
# discovery request at which it stops waiting for offers from servers,
# assuming that it has received at least one such offer
select-timeout {{ section.select_timeout|default(0, True) }};
{%- endif -%}

{%- if section.timeout is defined %}
timeout {{ section.timeout|default(120, True) }};
{%- endif -%}

{{ render_key(section, "send") }}
{{ render_key(section, "supersede") }}
{{ render_key(section, "prepend") }}
{{ render_key(section, "append") }}

{%- if section.reject is defined and section.reject|length > 0 %}
reject {{ section.reject|join(",\n    ") }};
{%- endif %}

{%- if section.request is defined and section.request|length > 0 %}
request {{ section.request|join(",\n    ") }};
{%- endif %}

{%- if section.require is defined and section.require|length > 0 %}
require {{ section.require|join(",\n    ") }};
{% endif -%}
{%- endmacro -%}

{# Actual template start #}
{%- from "linux/map.jinja" import network with context -%}
{%- set dhclient = network.get('dhclient', {}) %}
# dhclient.conf(5) file managed by salt-minion(1)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;
{{ render_section(dhclient) }}
{%- if dhclient.get("interface") -%}
{%- for iface_name, options in dhclient.interface.items() %}
{%- if network.interface.get(iface_name) and network.interface.get(iface_name).enabled == True
   and network.interface.get(iface_name).proto == 'dhcp' -%}
interface "{{ iface_name }}" {
    {{ render_section(options)|indent }}
}
{%- endif -%}
{%- endfor %}
{%- endif -%}