syntax = "proto3";

package xos;

import "google/protobuf/empty.proto";
import "google/api/annotations.proto";
import "common.proto";
import "xosoptions.proto";

{%- macro fieldOpts(field) -%}
  {%- set needComma=False -%}
  {%- set needBrack=True -%}
  {%- if field.max_length!=None -%}
    {%- if needBrack -%}[{%- endif -%}{%- if needComma -%}, {%- endif -%}{%- set needComma=True -%}{%- set needBrack=False -%}
    (val).maxLength = {{ field.max_length }}
  {%- endif -%}
  {%- if field.null==False -%}
    {%- if needBrack -%}[{%- endif -%}{%- if needComma -%}, {%- endif -%}{%- set needComma=True -%}{%- set needBrack=False -%}
    (val).nonNull= true
  {%- endif -%}
  {%- if field.related and field.related.model and field.related.model.__name__ -%}
    {%- if needBrack -%}[{%- endif -%}{%- if needComma -%}, {%- endif -%}{%- set needComma=True -%}{%- set needBrack=False -%}
    (foreignKey).modelName = "{{ field.related.model.__name__ }}"
  {%- endif -%}
  {%- if not needBrack -%}]{%- endif -%}
{%- endmacro %}

// Note: all fields are wrapped in a "oneof". This causes proto3 to always send
// fields that are set by the caller, regardless if they are set to a default
// value. XOS uses this to know when to apply a default value.

{% for object in generator.all() %}

message {{ object.camel() }} {
  {%- for field in object.all_fields %}
    oneof {{ field.name }}_present {
    {%- if (field.get_internal_type() == "CharField") or (field.get_internal_type() == "TextField") or (field.get_internal_type() == "SlugField") %}
      string {{ field.name }} = {{ loop.index }} {{ fieldOpts(field) }};
    {%- elif field.get_internal_type() == "BooleanField" %}
      bool {{ field.name }} = {{ loop.index }};
    {%- elif field.get_internal_type() == "ForeignKey" %}
      int32 {{ field.name }}_id = {{ loop.index }} {{ fieldOpts(field) }};
    {%- elif field.get_internal_type() == "DateTimeField" %}
      float {{ field.name }} = {{ loop.index }};
    {%- elif field.get_internal_type() == "AutoField" %}
      int32 {{ field.name }} = {{ loop.index }};
    {%- elif field.get_internal_type() == "IntegerField" %}
      int32 {{ field.name }} = {{ loop.index }};
    {%- elif field.get_internal_type() == "PositiveIntegerField" %}
      uint32 {{ field.name }} = {{ loop.index }};
    {%- elif field.get_internal_type() == "FloatField" %}
      float {{ field.name }} = {{ loop.index }};
    {%- elif field.get_internal_type() == "GenericIPAddressField" %}
      string {{ field.name }} = {{ loop.index }};
    {%- else %}
      UNKNOWN {{ field.get_internal_type() }} {{ field.name }} = {{ loop.index }};
    {%- endif %}
    }
  {%- endfor -%}
  {%- for ref in object.reverse_refs %}
    repeated int32 {{ ref.related_name }}_ids  = {{ loop.index+100 }} [(reverseForeignKey).modelName = "{{ ref.camel() }}"];
  {%- endfor %}
}

message {{ object.camel() }}s {
    repeated {{ object.camel() }} items = 1;
}

{% endfor %}

service xos {
{% for object in generator.all() %}
  rpc List{{ object.camel() }}(google.protobuf.Empty) returns ({{ object.camel() }}s) {
        option (google.api.http) = {
            get: "/xosapi/v1/{{ object.app_name }}/{{ object.plural() }}"
        };
  }
  rpc Filter{{ object.camel() }}(Query) returns ({{ object.camel() }}s) {
  }
  rpc Get{{ object.camel() }}(ID) returns ({{ object.camel() }}) {
        option (google.api.http) = {
            get: "/xosapi/v1/{{ object.app_name }}/{{ object.plural() }}/{id}"
        };
  }
  rpc Create{{ object.camel() }}({{ object.camel() }}) returns ({{ object.camel() }}) {
        option (google.api.http) = {
            post: "/xosapi/v1/{{ object.app_name }}/{{ object.plural() }}"
            body: "*"
        };
  }
  rpc Update{{ object.camel() }}({{ object.camel() }}) returns ({{ object.camel() }}) {
        option (google.api.http) = {
            put: "/xosapi/v1/{{ object.app_name }}/{{ object.plural() }}/{id}"
            body: "*"
        };
  }
  rpc Delete{{ object.camel() }}(ID) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            delete: "/xosapi/v1/{{ object.app_name }}/{{ object.plural() }}/{id}"
        };
  }
{% endfor %}
}

