/*
  Сервис реализует функционал управления привилегиями.
  Привилегии это услуги на квартиру со статусами, в их число входят привилегии которые можно подключить, но ещё не приобретены
*/
syntax = "proto3";

import "google/api/annotations.proto";
import "google/api/field_behavior.proto";
import "google/protobuf/descriptor.proto";

package keyapis.subscription.v1;

option java_package = "ru.keyapis.subscription.v1";
option java_outer_classname = "KeyapisSubscriptionV1Proto";
option java_multiple_files = false;
option java_string_check_utf8 = true;
option go_package = "/keyapis_subscription_v1";
option cc_enable_arenas = true;
option csharp_namespace = "Keyapis.Subscription.V1";
option objc_class_prefix = "KEYAPISSUBSCRIPTIONV1";
option php_namespace = "Keyapis\\Subscription\\V1";
option ruby_package = "Keyapis::Subscription::V1";
option optimize_for = LITE_RUNTIME;

// Сервис привилегий
service PrivilegeService {
  // Метод получения привилегий.
  // Метод доступен для: admin, master, service, ltp_first, application(subscription:read или subscription:edit)
  rpc GetPrivilegeList(GetPrivilegeListRequest) returns (stream GetPrivilegeListResponse) {
    option (google.api.http) = {
      get: "/subscription/api/v1/privilege/list"
    };
  }
  // Метод получения количества привилегий.
  // Метод доступен для: admin, master, service, ltp_first, application(subscription:read или subscription:edit)
  rpc GetPrivilegeCount(GetPrivilegeCountRequest) returns (GetPrivilegeCountResponse) {
    option (google.api.http) = {
      get: "/subscription/api/v1/privilege/count"
    };
  }
  // Метод проверки привилегии.
  // Метод доступен для: admin, master, service, ltp_first, application(subscription:read или subscription:edit)
  rpc GetPrivilegeCheck(GetPrivilegeCheckRequest) returns (GetPrivilegeCheckResponse) {
    option (google.api.http) = {
      get: "/subscription/api/v1/privilege/check/{orpon}/{flat_number}/{privilege_type}"
    };
  }
}

// Привилегия
message Privilege {
  // ОРПОН.
  // Идентификатор дома.
  // Уникальный ключ: поля в порядке 1,2,3
  int64 orpon = 1 [(google.api.field_behavior) = REQUIRED];
  // Номер квартиры
  string flat_number = 2 [(google.api.field_behavior) = REQUIRED];
  // Типы привилегий
  enum Type {
    // Значение не указано
    TYPE_UNKNOWN = 0;
    // Умный домофон.
    // Базовые функции.
    // Право доступа к разделу с домофонами и калиткаи.
    // Действие.
    // Закрывает услуги: get_devices_intercom
    INTERCOM_USE = 1;
    // Умный домофон.
    // Базовые функции.
    // Право использовать функционал открытия двери домофона и калитки.
    // Действие.
    // Закрывает услуги: post_devices_open_intercom
    INTERCOM_OPEN = 2;
    // Умный домофон.
    // Коды.
    // Право использовать функционал кодов домофонов и калиток.
    // Действие.
    // Закрывает услуги: get_devices_codes_intercom, post_devices_codes_intercom, delete_devices_codes_intercom
    INTERCOM_CODE_USE = 3;
    // Умный домофон.
    // Ключи.
    // Право использовать функционал физических ключей домофонов и калиток.
    // Действие.
    // Закрывает услуги: get_devices_rfids_intercom, post_devices_rfids_barrier, delete_devices_rfids_barrier
    INTERCOM_RFID_USE = 4;
    // Умный домофон.
    // События.
    // Право использовать функционал журнала событий домофонов и калиток.
    // Действие.
    // Закрывает услуги: get_events_intercom
    INTERCOM_EVENT_USE = 5;
    // Умный домофон.
    // Камеры.
    // Право использовать функционал просмотра камер и лайв видео с домофонов и калиток.
    // Действие.
    // Закрывает услуги: get_devices_camera_intercom
    INTERCOM_CAMERA_USE = 6;
    // Умный домофон.
    // Камеры.
    // Право использовать функционал архива видео с камер домофонов и калиток.
    // Действие.
    // Закрывает услуги: get_video_archive_intercom
    INTERCOM_CAMERA_ARCHIVE = 7;
    // Умный домофон.
    // Переадресация.
    // Право перенаправления входящих вызова от домофона в приложения, используется только на сервере.
    // Поведение.
    // Закрывает услуги: devices_call_redirect_to_mobile_app_behavior
    INTERCOM_CALLREDIRECT_APP = 8;
    // Умный домофон.
    // Переадресация.
    // Право перенаправление входящих вызовов от домофона на номера ТФОП, используется только на сервере.
    // Поведение.
    // Закрывает услуги: devices_call_redirect_to_pstn_behavior
    INTERCOM_CALLREDIRECT_PSTN = 9;
    // Умный домофон.
    // Переадресация.
    // Право перенаправление входящих вызовов от домофона на номера SIP, используется только на сервере.
    // Поведение.
    // Закрывает услуги: devices_call_redirect_to_sip_behavior
    INTERCOM_CALLREDIRECT_SIP = 10;
    // Умный шлагбаум.
    // Базовые функции.
    // Право доступа к разделу шлагбаумов.
    // Действие.
    // Закрывает услуги: get_devices_barrier
    BARRIER_USE = 11;
    // Умный шлагбаум.
    // Базовые функции.
    // Право использовать функционала поднятия стрелы шлагбаума.
    // Действие.
    // Закрывает услуги: post_devices_open_barrier
    BARRIER_OPEN = 12;
    // Умный шлагбаум.
    // Коды.
    // Право использовать функционал открытия шлагбаума по звонку на короткий номер.
    // Действие.
    // Закрывает услуги: get_devices_codes_barrier, post_devices_codes_barrier, delete_devices_codes_barrier
    BARRIER_CODE_USE = 13;
    // Умный шлагбаум.
    // События.
    // Право использовать функционал журнала событий шлагбаума.
    // Действие.
    // Закрывает услуги: get_events_barrier
    BARRIER_EVENT_USE = 14;
    // Умный шлагбаум.
    // Камеры.
    // Право использовать функционал просмотра камер и лайв видео с шлагбаумов.
    // Действие.
    // Закрывает услуги: get_devices_camera_barrier
    BARRIER_CAMERA_USE = 15;
    // Умный шлагбаум.
    // Камеры.
    // Право использовать функционал архива видео с камер, направленных на шлагбаум.
    // Действие.
    // Закрывает услуги: get_video_archive_barrier
    BARRIER_CAMERA_ARCHIVE = 16;
    // Распознавание лица.
    // Фото.
    // Право доступа к разделу распознавания лиц.
    // Действие.
    // Закрывает услуги: get_photo_fr_intercom, fr_intercom_access_behavior, post_photo_fr_intercom, delete_photo_fr_intercom
    FR_USE = 17;
    // Телеметрия.
    // Базовые функции.
    // Право доступа к разделу показаний приборов учёта.
    // Действие.
    // Закрывает услуги: get_telemetry_rooms_layout
    TELEMETRY_USE = 18;
    // Камеры.
    // Базовые функции.
    // Право доступа к разделу камер и лайв видео с них.
    // Действие.
    // Закрывает услуги: get_devices_camera, get_events_camera, get_devices_camera_access_control_panel, get_devices_camera_barrier, get_devices_camera_intercom
    CAMERA_USE = 19;
    // Камеры.
    // Базовые функции.
    // Право использовать функционал архива видео с камер видеонаблюдения.
    // Действие.
    // Закрывает услуги: get_video_archive, get_video_archive_access_control_panel
    CAMERA_ARCHIVE = 20;
    // Умный домофон.
    // Переадресация.
    // Право приёма входящих вызовов от домофона на аналоговую трубку, используется только на сервере.
    // Поведение.
    // Закрывает услуги: devices_call_to_cms_phones_behavior
    INTERCOM_CMS_PHONES_USE = 21;
    // Умный домофон.
    // Переадресация.
    // Право приёма входящих вызовов от домофона на аналоговую трубку, используется только на сервере.
    // Поведение.
    // Закрывает услуги: get_events_camera
    CAMERA_EVENT_USE = 22;
  }
  // Тип привилегии
  Type type = 3 [(google.api.field_behavior) = REQUIRED];
  // Типы состояний привилегий
  enum StateType {
    // Значение не указано
    STATE_TYPE_UNKNOWN = 0;
    // Услуга доступная для подключения на доме пользователя, но не активна.
    // Услуга есть в доступных КВ на ОРПОН, но её нет у пользователя
    CAN_BE_PAID = 1;
    // Услуга не оплачена и не активна.
    // Услуга есть в подписке в статусе: BLOCKED
    NOT_PAID = 2;
    // Услуга отключается, но ещё активна.
    // Услуга есть в подписке в статусе: SCHEDULED_CANCELED
    TURNS_OFF = 3;
    // Услуга в промо-периоде и активна.
    // Услуга есть в подписке в статусе: SETUP.
    // Обычно так создают промоподписки
    PROMO = 4;
    // Услуга оплачена и активна.
    // Услуга есть в подписке в статусе: ACTIVE.
    // Либо услуга есть в подписке с неблокируемой услугой
    PAID = 5;
  }
  // Состояние привилегии
  StateType state_type = 4 [(google.api.field_behavior) = REQUIRED];
}
// Фильтр по привилегиям
message PrivilegeFilter {
  // По ОРПОНам
  repeated int64 orpons = 1;
  // Номера квартир
  repeated string flat_numbers = 2;
  // По типам привилегий
  repeated Privilege.Type types = 3;
  // По состояниям привилегий
  repeated Privilege.StateType state_types = 4;

  // Ошибка валидации фильтра по привилегиям.
  // Эти проверки выполняются до обращения в базу данных
  message ValidationError {
    // Причины:
    // - Формат ОРПОН некорректен;
    // - Передано отрицательное значение
    message OrponsInvalid {}
    // Причины:
    // - Формат квартиры некорректен (например, длина номера квартира более 4 знаков);
    // - Номер квартиры содержит буквы
    message FlatNumbersInvalid {}

    // Причина ошибки
    oneof reason {
      // Формат ОРПОН некорректен
      OrponsInvalid orpons = 1;
      // Формат квартиры некорректен
      FlatNumbersInvalid flat_numbers = 2;
    }
  }
}
// Пагинация по привилегиям
message PrivilegePaging {
  // Справочник типов значений сортировки
  enum OrderByType {
    // Значение не указано
    ORDER_BY_TYPE_UNKNOWN = 0;
    // По уникальному ключу: orpon+flat_number+type
    KEY = 1;
  }
  // Тип значения сортировки.
  // По умолчанию: KEY
  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 ValidationError {
    // Причины:
    // - Значение количества < 0 или > 100
    message LimitInvalid {}
    // Причины:
    // - Значение сдвига < 0
    message OffsetInvalid {}

    // Причина ошибки
    oneof reason {
      // Количество передано некорректно
      LimitInvalid limit = 1;
      // Сдвиг передан некорректно
      OffsetInvalid offset = 2;
    }
  }
}

// Запрос получения привилегий
message GetPrivilegeListRequest {
  // Фильтр
  PrivilegeFilter filter = 1;
  // Вариант разбиения на страницы
  oneof pagination {
    // Пагинация
    PrivilegePaging paging = 2;
  }
}
// Ответ на запрос получения привилегий
message GetPrivilegeListResponse {
  // Ошибка запроса получения привилегий
  message Error {
    // Причина ошибки
    oneof reason {
      // Ошибка фильтрации по страницам
      PrivilegeFilter.ValidationError privilege_filter_validation = 1;
      // Ошибка пагинации по страницам
      PrivilegePaging.ValidationError privilege_paging_validation = 2;
    }
  }
  // Тип результата
  oneof type {
    // Предоставленная привилегия
    Privilege data = 1;
    // Ошибка
    Error error = 2;
  }
}

// Запрос получения количества привилегий
message GetPrivilegeCountRequest {
  // Фильтр
  PrivilegeFilter filter = 1;
}
// Ответ на запрос получения количества привилегий
message GetPrivilegeCountResponse {
  // Ошибка запроса получения количества привилегий
  message Error {
    // Причина ошибки
    oneof reason {
      // Ошибка фильтрации по страницам по привилегиям
      PrivilegeFilter.ValidationError privilege_filter_validation = 1;
    }
  }
  // Тип результата
  oneof type {
    // Всего привилегий
    int32 data = 1;
    // Ошибка
    Error error = 2;
  }
}

// Запрос проверки предоставленной привилегии
message GetPrivilegeCheckRequest {
  // ОРПОН.
  // Идентификатор дома
  int64 orpon = 1 [(google.api.field_behavior) = REQUIRED];
  // Номер квартиры
  string flat_number = 2 [(google.api.field_behavior) = REQUIRED];
  // Тип привилегии
  Privilege.Type privilege_type = 3 [(google.api.field_behavior) = REQUIRED];
}
// Результат запроса метода проверки предоставленной привилегии
message GetPrivilegeCheckResponse {
  // Тип результата
  oneof type {
    // Доступна ли привилегия на квартире.
    // Вернётся true если статусы:
    // - PROMO;
    // - PAID;
    // - TURNS_OFF.
    // Вернётся false если статусы:
    // - NOT_PAID;
    // - CAN_BE_PAID;
    // - STATE_TYPE_UNKNOWN;
    // - Не найден
    bool data = 1;
  }
}
