{% 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])) }}"
  {%- set uniques = xproto_field_graph_components(m.fields, m) %}
  {%- if uniques %}
      unique_together = {{ xproto_tuplify(uniques) }}
  {%- 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 %}
  {% 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

      self.full_clean()

      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
