/*
  Сервис реализует функционал управления Точками учёта(ТУ)
*/
syntax = "proto3";

import "google/api/annotations.proto";
import "google/api/field_behavior.proto";
import "keyapis/telemetry_control/v1/keyapis_telemetry_control_device_v1.proto";

package keyapis.telemetry_control.v1;

option java_package = "ru.keyapis.telemetry_control.v1";
option java_outer_classname = "KeyapisTelemetryControlV1Proto";
option java_multiple_files = false;
option java_string_check_utf8 = true;
option go_package = "/keyapis_telemetry_control_v1";
option cc_enable_arenas = true;
option csharp_namespace = "Keyapis.TelemetryControl.V1";
option objc_class_prefix = "KEYAPISTELEMETRYCONTROLV1";
option php_namespace = "Keyapis\\TelemetryControl\\V1";
option ruby_package = "Keyapis::TelemetryControl::V1";
option optimize_for = LITE_RUNTIME;

// Сервис Точек учёта (ТУ).
// Авторизация:
//   - Authorization: Bearer.
//   - X-Api-Key: apiKey
service MetricPointService {
  // Метод получения ТУ.
  // Разрешения: telemetry_control:metric_point:card, telemetry_control:metric_point:card:own.
  // Метод доступен для: Token: admin, service, bti, seller, application, owner, employee. Без учета разрешений.
  // Метод доступен для: ApiKey: При наличии разрешений
  rpc GetMetricPoint(GetMetricPointRequest) returns (GetMetricPointResponse) {
    option (google.api.http) = {
      get: "/telemetry_control/api/v1/metric_point/{id}"
    };
  }
  // Метод получения списка ТУ.
  // Разрешения: telemetry_control:metric_point:list, telemetry_control:metric_point:list:own.
  // Метод доступен для: Token: admin, service, bti, seller, application, owner, employee. Без учета разрешений.
  // Метод доступен для: ApiKey: При наличии разрешений
  rpc GetMetricPointList(GetMetricPointListRequest) returns (stream GetMetricPointListResponse) {
    option (google.api.http) = {
      get: "/telemetry_control/api/v1/metric_point/list"
    };
  }
  // Метод получения количества ТУ.
  // Разрешения: telemetry_control:metric_point:list, telemetry_control:metric_point:list:own.
  // Метод доступен для: Token: admin, service, bti, seller, application, owner, employee. Без учета разрешений.
  // Метод доступен для: ApiKey: При наличии разрешений
  rpc GetMetricPointCount(GetMetricPointCountRequest) returns (GetMetricPointCountResponse) {
    option (google.api.http) = {
      get: "/telemetry_control/api/v1/metric_point/count"
    };
  }
  // Метод сохранения ТУ.
  // Поддерживает создание и обновление.
  // Метод доступен для: Token: admin, service, bti, seller, application, owner, employee. Без учета разрешений
  rpc PostMetricPoint(PostMetricPointRequest) returns (PostMetricPointResponse) {
    option (google.api.http) = {
      post: "/telemetry_control/api/v1/metric_point"
      body: "*"
    };
  }
  // Метод удаления ТУ.
  // Метод доступен для: Token: admin, service, bti, seller, application, owner, employee. Без учета разрешений
  rpc DeleteMetricPoint(DeleteMetricPointRequest) returns (DeleteMetricPointResponse) {
    option (google.api.http) = {
      delete: "/telemetry_control/api/v1/metric_point/{id}"
    };
  }
}

// Запрос получения ТУ
message GetMetricPointRequest {
  // Идентификатор ТУ
  string id = 1 [(google.api.field_behavior) = REQUIRED];
}

// Ответ на запрос получения ТУ
message GetMetricPointResponse {
  // Тип результата
  oneof type {
    // Точка учета
    Device.MetricPoint data = 1;
  }
}

// Запрос получения списка ТУ
message GetMetricPointListRequest {
  // Фильтр
  MetricPointFilter filter = 1;
  // Вариант разбиения на страницы
  oneof pagination {
    // Пагинация
    MetricPointPaging paging = 2;
  }
}

// Пагинация
message MetricPointPaging {
  // Ошибка валидации постраничной пагинации по ТУ.
  // Эти проверки выполняются до обращения в базу данных
  message ValidationError {
    // Причины:
    // - Значение количества < 0 или > 100
    message LimitInvalid {}
    // Причины:
    // - Значение сдвига < 0
    message OffsetInvalid {}

    // Причина ошибки
    oneof reason {
      // Количество передано некорректно
      LimitInvalid limit = 1;
      // Сдвиг передан некорректно
      OffsetInvalid offset = 2;
    }
  }
  // Справочник типов значений сортировки
  enum OrderByType {
    // Значение не указано
    ORDER_BY_TYPE_UNKNOWN = 0;
    // По идентификатору
    ID = 1;
    // По типу энергоресурса
    METRIC_TYPE = 2;
    // По типу статуса
    STATUS_TYPE = 3;
    // По Номеру помещения
    ROOM_NUMBER = 4;
    // По Лейблу помещения
    ROOM_LABEL = 5;
    // По идентификатору объекта строительства
    BUILDING_ID = 6;
  }
  // Тип значения сортировки.
  // По умолчанию: ID
  OrderByType order_by_type = 1;
  // Справочник типов направлений сортировки
  enum DirectionType {
    // Значение не указано
    DIRECTION_TYPE_UNKNOWN = 0;
    // От большего к меньшему
    DESC = 1;
    // От меньшего к большему
    ASC = 2;
  }
  // Тип направления сортировки.
  // По умолчанию: DESC
  DirectionType direction_type = 2;
  // Количество.
  // Минимальное значение: 1.
  // Максимальное значение: 100.
  // По умолчанию: 20.
  // Если значение 0 (не передано) то выставляем значение по умолчанию
  int32 limit = 3;
  // Сдвиг.
  // По умолчанию: 0
  int32 offset = 4;
}

// Фильтр для запроса точек учета.
// При передаче массива в параметр фильтра элементы массива работают в выборке через ИЛИ.
// При передаче нескольких разных параметров фильтра они работают в выборке через И
message MetricPointFilter {
  // Ошибки валидации.
  // Эти проверки выполняются до обращения в базу данных
  message ValidationError {
    // Путь к полю в формате наименования protobuf
    string path = 1 [(google.api.field_behavior) = REQUIRED];
    // Валидационное сообщение
    string message = 2 [(google.api.field_behavior) = REQUIRED];
  }
  // По типу энергоресурса
  repeated Device.MetricPoint.MetricType device_metric_point_metric_types = 1;
  // По типу статуса
  repeated Device.MetricPoint.StatusType device_metric_point_status_types = 2;
  // По Номеру помещения
  repeated string room_numbers = 3;
  // По Лейблу помещения
  repeated string room_labels = 4;
  // По идентификаторам объекта строительства
  repeated int32 building_ids = 5;
  // По ФИАС
  repeated string fias_ids = 6;
  // По ID привязанных через индикаторы ПУ
  repeated int32 device_ids = 7;
  // По серийным номерам привязанных через индикаторы ПУ
  repeated string device_serial_numbers = 8;
  // По ОРПОНам
  repeated int64 orpons = 9;
}

// Ответ на запрос получения списка ТУ
message GetMetricPointListResponse {
  // Ошибка запроса получения списка ТУ
  message Error {
    // Причина ошибки
    oneof reason {
      // Ошибка фильтрации
      MetricPointFilter.ValidationError metric_point_filter_validation = 1;
      // Ошибка пагинации  по страницам
      MetricPointPaging.ValidationError metric_point_paging_validation = 2;
    }
  }
  // Тип результата
  oneof type {
    // Точка учета
    Device.MetricPoint data = 1;
    // Ошибка
    Error error = 2;
  }
}

// Запрос получения количества ТУ
message GetMetricPointCountRequest {
  // Фильтр по ТУ
  MetricPointFilter filter = 1;
}

// Ответ на запрос получения количества ТУ
message GetMetricPointCountResponse {
  // Ошибка запроса получения количества ТУ
  message Error {
    // Причина ошибки
    oneof reason {
      // Ошибка фильтрации
      MetricPointFilter.ValidationError metric_point_filter_validation = 1;
    }
  }
  // Тип результата
  oneof type {
    // Всего ТУ
    int32 data = 1;
    // Ошибка
    Error error = 2;
  }
}

// Запрос сохранения ТУ
message PostMetricPointRequest {
  // Точка учета
  Device.MetricPoint data = 1 [(google.api.field_behavior) = REQUIRED];
}

// Ответ на запрос сохранения ТУ
message PostMetricPointResponse {
  // Ошибка запроса сохранения ТУ
  message Error {
    // Причина ошибки
    oneof reason {
      // Ошибка валидации
      ValidationError validation = 1;
    }
  }
  // Тип результата
  oneof type {
    // Точка учета
    Device.MetricPoint data = 1;
    // Ошибка
    Error error = 2;
  }
}

// Запрос удаления ТУ
message DeleteMetricPointRequest {
  // Идентификатор
  string id = 1 [(google.api.field_behavior) = REQUIRED];
}

// Ответ на запрос удаления ТУ
message DeleteMetricPointResponse {}

// Ошибки валидации.
// Эти проверки выполняются до обращения в базу данных
message ValidationError {
  // Путь к полю в формате наименования protobuf
  string path = 1 [(google.api.field_behavior) = REQUIRED];
  // Валидационное сообщение
  string message = 2 [(google.api.field_behavior) = REQUIRED];
}
