{% if options.legacy =='"True"' -%}
{% set legacy_tag = '_decl' %}
{% set legacy = True %}
from core.models.xosbase import *
from core.models import ServiceInstance, TenantWithContainer
{% else %}
{% set legacy = False %}
{% set legacy_tag = '' %}
{% if file_exists('../header.py') or file_exists('header.py')-%}from header import *
{% else %}
from core.models.xosbase import *
from core.models import ServiceInstance, TenantWithContainer
{% endif %}
{% endif %}

{% for m in proto.messages %}
{% if file_exists(m.name|lower+'_header.py') -%}from {{m.name|lower }}_header import *{% endif %}
{% if file_exists(m.name|lower+'_top.py') -%}{{ include_file(m.name|lower+'_top.py') }} {% endif %}

{%- for l in m.links -%}{% set peer_name=l.peer.name %}

{% if peer_name not in proto.message_names -%}
from core.models import {{ peer_name }} 
{%- endif -%}
{%- endfor -%}
{%- for b in m.bases -%}
{%- if b.name!='XOSBase' and 'Mixin' not in b.name %}
{% if b.name not in proto.message_names %}
from core.models import {{ b.name }}
{% endif %}
{%- endif -%}
{% endfor %}

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

{% endfor %}

{% for m in proto.messages %}
class {{ m.name }}{{ legacy_tag }}{{ xproto_base_def(m.name, m.bases, legacy_tag, proto.message_names) }}:
  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 %}

  KIND = {{ xproto_first_non_empty([m.options.kind, options.kind, options.name, "Set a kind in your xproto!"]) }}

  {% if m.options.owner_class_name %}
  OWNER_CLASS_NAME = {{ m.options.owner_class_name }}
  {% endif %}

  class Meta:
      app_label = {{ xproto_first_non_empty([m.options.app_label, options.app_label, options.name, "Set an app label in your xproto!"]) | lower}}
      # name = {{ xproto_first_non_empty([m.options.name, options.name, "Set a name in your xproto!"]) }}
      verbose_name = "{{ xproto_unquote(xproto_first_non_empty([m.options.verbose_name, m.name])) }}"

  # 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 %}
  {% if legacy and peer_name in proto.message_names %}{% set peer_tag = legacy_tag %}{% else %}{% set peer_tag = '' %}{% endif -%}
  {{ l.src_port }} = {{ xproto_django_link_type(l) }}( {%- if peer_name==m.name -%}'self'{%- else -%}{{ peer_name }}{{ peer_tag }} {%- endif -%}, {{ xproto_django_options_str(l, l.dst_port ) }} )
  {%- endfor %}

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

  # Generated methods
  def save(self, *args, **kwds):
      if not self.leaf_model_name:
          self.leaf_model_name = "{{ m.name }}"

      {% for policy,error in xproto_validations(m.options) %}
      policy_{{policy}}_validator(self, None)
      {% endfor %}

      try:
          base_save_in_attic = self.__xos_save_base(*args, **kwds)
      except AttributeError:
          base_save_in_attic = False

      if not base_save_in_attic:
          super({{ m.name }}{{ legacy_tag }}, 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 = True
      return verdict,"xos_default_policy"
      {% endif %}

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