syntax = "proto3";

package xos;

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

// 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 proto.messages|selectattr("is_included")|sort(attribute='name') %}
{% if object.name != 'XOSBase' -%}
message {{ object.name }} {
    {%- if object.name=='CordSubscriberRoot' %}
    option (contentTypeId) = "rcord.{{ object.name | lower }}";
    {%- else %}
    option (contentTypeId) = "{{ xproto_unquote(xproto_first_non_empty([object.options.name, object.options.app_label, options.name, context.app_label])) }}.{{ object.name | lower }}";
    {%- endif %}
    {%- set id_field = {'type':'int32', 'name':'id', 'options':{}} -%}
  {%- for field in xproto_fields(object, proto.message_table) | sort(attribute='id')%}
  {%- if field.options.type == "link" and field.options.link_type == "manytomany" %}
    repeated int32 {{ field.name }}_ids = {{ field.id }} [(manyToManyForeignKey).modelName = "{{ field.options.model }}"];
  {%- else %}
    oneof {{ field.name }}_present {
      {{ xproto_api_type(field) }} {{ field.name }}{% if field.link -%}_id{% endif %} = {{ field.id }} {{ xproto_api_opts(field) }};
    }
  {%- endif -%}
  {%- endfor -%}

  {%- for ref in xproto_rlinks(object, proto.message_table) | sort(attribute='id') %}
  {%- if '+' not in ref.src_port and '+' not in ref.dst_port %}
    repeated int32 {{ ref.src_port }}_ids  = {{ ref["id"] }} [(reverseForeignKey).modelName = "{{ ref.peer.name }}"];
  {%- endif -%}
  {%- endfor %}
  string class_names = 2046 [(bookkeepingState) = true];
  string self_content_type_id = 2047 [(bookkeepingState) = true];
}

message {{ xproto_pluralize(object) }} {
    repeated {{ object.name }} items = 1;
}

{%- endif %}
{% endfor %}

service xos {
{% for object in proto.messages | selectattr("is_included") | sort(attribute='name')%}
{% if object.name != 'XOSBase' -%}
  rpc List{{ object.name }}(google.protobuf.Empty) returns ({{ xproto_pluralize(object) }}) {
        option (googleapi.http) = {
        {%- if object.name=='CordSubscriberRoot' %}
            get: "/xosapi/v1/rcord/{{ xproto_pluralize(object) | lower }}"
        {%- else %}
            get: "/xosapi/v1/{{ xproto_unquote(xproto_first_non_empty([object.options.name, object.options.app_label, options.name, context.app_label])) }}/{{ xproto_pluralize(object) | lower }}"
        {%- endif %}
        };
  }
  rpc Filter{{ object.name }}(Query) returns ({{ xproto_pluralize(object) }}) {
  }
  rpc Get{{ object.name }}(ID) returns ({{ object.name }}) {
        option (googleapi.http) = {
        {%- if object.name=='CordSubscriberRoot' %}
            get: "/xosapi/v1/rcord/{{ xproto_pluralize(object) | lower }}/{id}"
        {%- else %}
            get: "/xosapi/v1/{{ xproto_unquote(xproto_first_non_empty([object.options.name, object.options.app_label, options.name, context.app_label])) }}/{{ xproto_pluralize(object) | lower }}/{id}"
        {%- endif %}
        };
  }
  rpc Create{{ object.name }}({{ object.name }}) returns ({{ object.name }}) {
        option (googleapi.http) = {
            post: "/xosapi/v1/{{ xproto_unquote(xproto_first_non_empty([object.options.name, object.options.app_label, options.name, context.app_label])) }}/{{ xproto_pluralize(object) | lower }}"
            body: "*"
        };
  }
  rpc Update{{ object.name }}({{ object.name }}) returns ({{ object.name }}) {
        option (googleapi.http) = {
            put: "/xosapi/v1/{{ xproto_unquote(xproto_first_non_empty([object.options.name, object.options.app_label, options.name, context.app_label])) }}/{{ xproto_pluralize(object) | lower }}/{id}"
            body: "*"
        };
  }
  rpc Delete{{ object.name }}(ID) returns (google.protobuf.Empty) {
        option (googleapi.http) = {
            delete: "/xosapi/v1/{{ xproto_unquote(xproto_first_non_empty([object.options.name, object.options.app_label, options.name, context.app_label])) }}/{{ xproto_pluralize(object) | lower }}/{id}"
        };
  }
{%- endif %}
{% endfor %}
}

