PROTOCOLS_TEMPLATE = """#
# Generated by "infrahubctl protocols"
#

from __future__ import annotations

from typing import TYPE_CHECKING, Optional

from infrahub_sdk.protocols import CoreNode, {{ base_protocols | join(', ') }}

if TYPE_CHECKING:
    {% if sync %}
    from infrahub_sdk.node import RelatedNodeSync, RelationshipManagerSync
    {% else %}
    from infrahub_sdk.node import RelatedNode, RelationshipManager
    {% endif %}
    from infrahub_sdk.protocols_base import (
        AnyAttribute,
        AnyAttributeOptional,
        String,
        StringOptional,
        Integer,
        IntegerOptional,
        Boolean,
        BooleanOptional,
        DateTime,
        DateTimeOptional,
        Dropdown,
        DropdownOptional,
        HashedPassword,
        HashedPasswordOptional,
        MacAddress,
        MacAddressOptional,
        IPHost,
        IPHostOptional,
        IPNetwork,
        IPNetworkOptional,
        JSONAttribute,
        JSONAttributeOptional,
        ListAttribute,
        ListAttributeOptional,
        URL,
        URLOptional,
    )
{% for generic in generics %}


class {{ generic.namespace + generic.name }}(CoreNode):
    {% if not generic.attributes|default([]) and not generic.relationships|default([]) %}
    pass
    {% endif %}
    {% for attribute in generic.attributes|default([]) %}
    {{ attribute | render_attribute }}
    {% endfor %}
    {% for relationship in generic.relationships|default([]) %}
    {{ relationship | render_relationship(sync) }}
    {% endfor %}
    {% if generic.hierarchical | default(false) %}
    {% if sync %}
    parent: RelatedNodeSync
    children: RelationshipManagerSync
    {% else %}
    parent: RelatedNode
    children: RelationshipManager
    {% endif %}
    {% endif %}
{% endfor %}
{% for node in nodes %}


class {{ node.namespace + node.name }}({{ node.inherit_from | join(", ") or "CoreNode" }}):
    {% if not node.attributes|default([]) and not node.relationships|default([]) %}
    pass
    {% endif %}
    {% for attribute in node.attributes|default([]) %}
    {{ attribute | render_attribute }}
    {% endfor %}
    {% for relationship in node.relationships|default([]) %}
    {{ relationship | render_relationship(sync) }}
    {% endfor %}
    {% if node.hierarchical | default(false) %}
    {% if sync %}
    parent: RelatedNodeSync
    children: RelationshipManagerSync
    {% else %}
    parent: RelatedNode
    children: RelationshipManager
    {% endif %}
    {% endif %}
{% endfor %}
{% for node in profiles %}


class {{ node.namespace + node.name }}({{ node.inherit_from | join(", ") or "CoreNode" }}):
    {% if not node.attributes|default([]) and not node.relationships|default([]) %}
    pass
    {% endif %}
    {% for attribute in node.attributes|default([]) %}
    {{ attribute | render_attribute }}
    {% endfor %}
    {% for relationship in node.relationships|default([]) %}
    {{ relationship | render_relationship(sync) }}
    {% endfor %}
    {% if node.hierarchical | default(false) %}
    {% if sync %}
    parent: RelatedNodeSync
    children: RelationshipManagerSync
    {% else %}
    parent: RelatedNode
    children: RelationshipManager
    {% endif %}
    {% endif %}
{% endfor %}

"""
