{% for m in proto.messages %}{% if not m.options.skip_django -%}
{%- if xproto_list_evaluates_true([m.options.custom_python, m.options.legacy, options.custom_python, options.legacy]) -%}
{%- set legacy_tag = '_decl' -%}
{%- set legacy = True -%}
{%- else -%}
{%- set legacy_tag = '' -%}
{%- set legacy = False -%}
{%- endif -%}
{% if m.options.custom_header %}
from {{ m.options.custom_header|replace('"','') }} import *
{% else %}
from core.models.xosbase import *
{% endif %}

{%- for l in m.links %}

{% if l.peer.name != m.name %}
from {{ l.peer.name | lower }} import {{ l.peer.name }} 
{% endif %}

{%- endfor %}
{% if m.name!='XOSBase' and 'Mixin' not in m.name %}
import security
{% if m.name!='Privilege' %}
from privilege import Privilege
{% endif %}
{% endif %}
{% for b in m.bases %}
{% if b.name!='XOSBase' and 'Mixin' not in b.name %}
from {{b.name | lower}} import {{ b.name }}
{% endif %}
{% endfor %}

{% for policy,error in xproto_validations(m.options) %}
{{ xproto_fol_to_python_validator(policy, proto.policies[policy], m, error) }}
{% endfor %}

class {{ m.name }}_decl{{ xproto_base_def(m.name, m.bases) }}:
  plural_name = "{{ xproto_pluralize(m) }}"

  {%- set feedback_state_fields = xproto_optioned_fields_to_list(xproto_base_fields(m, proto.message_table) + m.fields, 'feedback_state', 'True')  %}
  {%- if feedback_state_fields|length > 0 %}
  feedback_state_fields = {{ feedback_state_fields }}
  {%- endif %}

{#  {% if m.options.no_sync or m.options.no_policy %}#}
{#  {% if m.options.no_sync -%}#}
{#  # Removing synchronizer feedback state from model#}
{#  backend_status = None#}
{#  backend_code = None#}
{#  {%- endif %}#}
{#  {% if m.options.no_policy -%}#}
{#  # Removing model policy feedback state from model#}
{#  policy_code = None#}
{#  policy_status = None#}
{#  {%- endif %}#}
{#  {% endif %}#}

  # Primitive Fields (Not Relations)
  {% for f in m.fields %}
  {%- if not f.link -%}
  {{ f.name }} = {{ xproto_django_type(f.type, f.options) }}( {{ xproto_django_options_str(f) }} )
  {% endif %}
  {%- endfor %}

  # Relations
  {% for l in m.links %}{% set peer_name=l.peer.name %}
  {{ l.src_port }} = {{ xproto_django_link_type(l) }}( {%- if peer_name==m.name -%}'self'{%- else -%}{{ peer_name }} {%- endif -%}, {{ xproto_django_link_options_str(l, l.dst_port ) }} )
  {%- endfor %}

  # Meta
  class Meta:
  {%- set uniques = xproto_field_graph_components(m.fields, m) %}
  {%- if uniques %}
      unique_together = {{ xproto_tuplify(uniques) }}
  {%- endif %}
  {%- if xproto_is_true(m.options.abstract) %}
      abstract=True
  {%- endif %}
      pass

  {% if file_exists(m.name|lower + '_model.py') -%}{{ include_file(m.name|lower + '_model.py') | indent(width=2)}}{%- endif %}
  pass

  {% if m.name!='XOSBase' and 'Mixin' not in m.name %}
  # Generated methods
  def save(self, *args, **kwds):
      if not self.leaf_model_name:
          self.leaf_model_name = "{{ m.name }}"

      try:
          self.__xos_save_base(*args, **kwds)
      except AttributeError:
          pass

      if not self.deleted:
          self.full_clean()

      {% for policy,error in xproto_validations(m.options) %}
      policy_{{policy}}_validator(self, None)
      {% endfor %}
      super({{ m.name }}_decl, self).save(*args, **kwds)

  def can_access(self, ctx):
      {% if m.policy %}
      verdict = security.{{m.policy}}_security_check(self, ctx)
      return verdict,"{{ m.policy }}"
      {% else %}
      verdict = XOS_GLOBAL_DEFAULT_SECURITY_POLICY
      return verdict,"xos_default_policy"
      {% endif %}
      
  {% endif %}

{# To maintain compatibility with migrations, we need to ensure that both the _decl and the non-_decl model #}
{# exist. So we automatically create all models as _decl, and then add these trivial stubs #}
{% if not legacy %}
class {{ m.name }}({{ m. name }}_decl):
    class Meta:
        proxy = True
{% endif %}

{% if file_exists(xproto_base_name(m.name)|lower+'_bottom.py') -%}{{ include_file(xproto_base_name(m.name)|lower+'_bottom.py') }}{% endif %}
{% endif %}{% endfor %}
