syntax = "proto3";

package xos;

import "google/protobuf/empty.proto";
import "google/api/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 (google.api.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 (google.api.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 (google.api.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 (google.api.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 (google.api.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 %}
}

