/*
 * Created by jonathan.jesperson@pluto.tv on 10/21/2020.
 * Copyright (c) PlutoTV Inc 2020.
 */

syntax = "proto3";

package episodepackage;

option go_package = "github.com/Pluto-tv/service-dal/golang_client";
option java_package = "tv.pluto.ip.dal.episode";

service EpisodeManager {
  // GetAll (Server Stream)
  //
  rpc GetAll(GetAllRequest) returns (stream Episode) {}

  // GetById (Unary)
  //
  rpc GetById(GetByIdRequest) returns (GetByIdResponse) {}

  // GetByIds (Unary)
  //
  rpc GetByIds(GetByIdsRequest) returns (GetByIdsResponse) {}

  // GetByIds (Unary)
  //
  rpc GetAllIds(GetAllIdsRequest) returns (GetAllIdsResponse) {}

  // GetPopulatedEpisodeById (Unary)
  // The default populated episode when no `populate` is provided is the entire populated object. For performance
  // reason it may be desirable to request less / only needed values
  rpc GetPopulatedEpisodeById(GetPopulatedEpisodeByIdRequest) returns (GetPopulatedEpisodeByIdResponse) {}

  // GetEpisodesByClipId (Unary)
  //
  rpc GetEpisodesByClipId(GetEpisodesByClipIdRequest) returns (GetEpisodesByClipIdResponse) {}

  // GetEpisodeIdsBySeriesIds (Unary)
  //
  rpc GetEpisodeIdsBySeriesIds(GetEpisodeIdsBySeriesIdsRequest) returns (GetEpisodeIdsBySeriesIdsResponse) {}

  // GetPopulatedEpisodesByClipId (Unary)
  //
  rpc GetPopulatedEpisodesByClipId(GetPopulatedEpisodesByClipIdRequest) returns (GetPopulatedEpisodesByClipIdResponse) {}

  // GetDocumentsUpdatedBetweenDates (Server Stream)
  //
  rpc GetDocumentsUpdatedBetweenDates(GetDocumentsUpdatedBetweenDatesRequest) returns (stream Episode) {}

  // GetAgeRangePopulatedEpisodeById (Unary)
  //
  rpc GetAgeRangePopulatedEpisodeById(GetAgeRangePopulatedEpisodeByIdRequest) returns (GetAgeRangePopulatedEpisodeByIdResponse) {}

  // GetAgeRangePopulatedEpisodesByIds (Unary)
  //
  rpc GetAgeRangePopulatedEpisodesByIds(GetAgeRangePopulatedEpisodesByIdsRequest) returns (GetAgeRangePopulatedEpisodesByIdsResponse) {}

  // UpdateContentMamUniqueIdsByIds (Unary)
  //
  rpc UpdateContentMamUniqueIdsByIds(UpdateContentMamUniqueIdsByIdsRequest) returns (UpdateContentMamUniqueIdsByIdsResponse) {}

  // GetAllPaged (Unary)
  //
  rpc GetAllPaged(GetAllPagedRequest) returns (GetAllPagedResponse) {}

  // UpdateFields (Unary)
  //
  rpc UpdateFields(UpdateFieldsRequest) returns (UpdateFieldsResponse) {}

  // Create (Unary)
  //
  rpc Create(CreateRequest) returns (CreateResponse) {}

  // DeleteByIds (Unary)
  //
  rpc DeleteByIds(DeleteByIdsRequest) returns (DeleteByIdsResponse) {}

  // DeleteById (Unary)
  //
  rpc DeleteById(DeleteByIdRequest) returns (DeleteByIdResponse) {}

  // CFeedsSyncDocuments (Server Stream)
  //
  rpc CFeedsSyncDocuments(CFeedsSyncDocumentsRequest) returns (stream Episode) {}

  // CFeedsSyncAllIds (Server Stream)
  //
  rpc CFeedsSyncAllIds(CFeedsSyncAllIdsRequest) returns (stream Id) {}

  // GetEpisodeById (Unary)
  //
  // Deprecated. Will be removed once client (FW IVI) no longer using
  rpc GetEpisodeById(GetEpisodeByIdRequest) returns (GetEpisodeByIdResponse) {}

  // SetAdPodDurations (Unary)
  //
  rpc SetAdPodDurations(SetAdPodDurationsRequest) returns (Episode) {}

  // CalculateTotalAdPodsDuration (Unary)
  //
  rpc CalculateTotalAdPodsDuration(CalculateTotalAdPodsDurationRequest) returns (Episode) {}

  // GetChannelLibrary (Unary)
  //
  rpc GetChannelLibrary(GetChannelLibraryRequest) returns (GetChannelLibraryResponse) {}

  // GetEpisodeUsingExternalId (Unary)
  //
  rpc GetEpisodeUsingExternalId(GetEpisodeUsingExternalIdRequest) returns (GetEpisodeUsingExternalIdResponse) {}

  // GetEpisodesByIds (unary)
  //
  rpc GetEpisodesByIds(GetEpisodesByIdsRequest) returns (GetEpisodesByIdsResponse) {}

  // GetEpisodeByNameSeriesAndActiveRegion (unary)
  //
  rpc GetEpisodeByNameSeriesAndActiveRegion(GetEpisodeByNameSeriesAndActiveRegionRequest) returns (GetEpisodeByNameSeriesAndActiveRegionResponse) {}

  // GetEpisodeBySeriesSeasonAndNumber (unary)
  //
  rpc GetEpisodeBySeriesSeasonAndNumber(GetEpisodeBySeriesSeasonAndNumberRequest) returns (GetEpisodeBySeriesSeasonAndNumberResponse) {}

  // GetPopulatedEpisodesByIds (Unary)
  // The default populated episode when no `populate` is provided is the entire populated object. For performance
  // reason it may be desirable to request less / only needed values
  rpc GetPopulatedEpisodesByIds(GetPopulatedEpisodesByIdsRequest) returns (GetPopulatedEpisodesByIdsResponse) {}

  // UnsetNextTimeline (Unary)
  //
  rpc UnsetNextTimeline(UnsetNextTimelineRequest) returns (UnsetNextTimelineResponse) {}

  // UpdateLastAired (Unary)
  //
  rpc UpdateLastAired(UpdateLastAiredRequest) returns (UpdateLastAiredResponse) {}
}

message GetEpisodesByIdsRequest {
  repeated string ids = 1;
}

message GetEpisodesByIdsResponse {
  repeated EpisodeComputed documents = 1;
}

message SeriesName {
  string id = 1;
  string name = 2;
}
message EpisodeComputed {
  string id = 1;
  string name = 2;
  string rating = 3;
  int32 season = 4;
  int32 number = 5;
  repeated AgeRange age_range = 6;
  string tmsid = 7;
  int32 duration = 8;
  string last_aired = 9;
  string first_aired = 10;
  NextTimelineDetails next_timeline = 11;
  SeriesName series = 12;
  int32 allotment = 13;
  bool featured = 14;
  bool flagged = 15;
  AvailabilityWindows availability_windows = 16;
  repeated SourceDetails sources = 17;
  string updated_at = 18;
  bool all_clips_ready = 19;
  bool is_available_now = 20;
  bool has_unique_provider = 21;
  bool has_mixed_provider_with = 22;
  bool has_clip_with_empty_sources = 23;
  bool has_linear_availability_windows = 24;
  string author = 25;
  string status = 26;
  string genre = 27;
  bool has_ad_pods = 28;
  bool published = 29;

  string created_at = 30;
  string display_name = 31;
  string display_on_guide = 32;
  bool ad_free = 33;
  bool ad_pods_verified = 34;
  string slug = 35;
  string uid = 36;
  int32 ad_pods_duration = 37;
  string description = 38;
  string summary = 39;
  string notes = 40;
  string category = 41;
  string sub_category = 42;
  string sub_genre = 44;
  repeated string tags = 45;
  bool live_broadcast = 48;
  string premiere = 49;
  bool derivative = 50;
  bool is_feed = 51;
  repeated string feeds = 52;
  string parent = 53;
  repeated Content content = 54;
  repeated Backups backups = 55;
  repeated string channels = 56;
  Image thumbnail = 57;
  Image featured_image = 58;
  Image partner_logo = 59;
  Image poster = 60;
  Image screenshot16_9 = 61 [json_name = "screenshot16_9"];
  Image screenshot4_3 = 62 [json_name = "screenshot4_3"];
  Meta meta = 63;
  DistributeAs distribute_as = 64;
  PlaybackRestrictions playback_restrictions = 65;
  repeated string vod_category_entries = 66;
  bool pluto_tv_o_o = 67;
  string active_region = 68; // not in schema
  string metadata_language = 69; // not in schema
  repeated string region_filter = 70;
  bool dash_enabled = 71;
  string content_u_u_i_d = 72;
  Image poster16_9 = 73 [json_name = "poster16_9"];
  repeated CustomReferenceValue custom_references = 74;
  repeated string rating_descriptors = 75;
  repeated ExternalId external_ids = 77;
}

message NextTimelineDetails {
  string id = 1;
  string channel = 2;
  string start = 3;
}

message EpisodeById {}

message ExternalId {
  string key = 1;
  string value = 2;
}

message GetEpisodeUsingExternalIdRequest {
  string key = 1;
  string value = 2;
  string series = 3;
  string category = 4;
  string sub_category = 5;
  string genre = 6;
  string sub_genre = 7;
  repeated string tags = 8;
  string active_region = 9;
  repeated string channels = 10;
  string clipId = 11;
  int32 duration = 12;
  bool published = 13;
}

message GetEpisodeUsingExternalIdResponse {
  repeated Episode documents = 1;
}

message GetAllIdsRequest {
  bool published = 1;
  // how many results to return default 0 (no limit)
  int32 limit = 2;
  // where to begin page default 0
  int32 offset = 3;
  // when set to true the `total count` metadata will not be calculated
  // this can save some performance as count is additional query
  bool disable_total_count = 4;
  bool vod = 5;
  repeated GetAllPagedSort sort = 6;
}

message EpisodeSeriesIds {
  string id = 1;
  string series = 2;
  string updated_at = 3;
}

message GetAllIdsResponse {
  repeated EpisodeSeriesIds ids = 1;
  Metadata metadata = 2;
}

message CFeedsSyncAllIdsRequest {
  bool published = 1;
}

message Id {
  string id = 1;
}

message CFeedsSyncDocumentsRequest {
  // Expressed as a valid javascript Date, https://en.wikipedia.org/wiki/ISO_8601
  string last_run_at = 1;
  bool published = 2;
  bool vod = 3;
}

message UpdateFieldsRequest {
  string id = 1;
  Episode document = 2;
  repeated string update_fields = 3;
}

message UpdateFieldsResponse {
  Episode document = 1;
}

message CreateRequest {
  Episode document = 1;
}

message CreateResponse {
  EpisodeCreate document = 1;
}

message GetAllRequest {
  string region = 1;
}

message DeleteByIdsRequest {
  repeated string ids = 1;
}

message DeleteByIdsResponse {
  int64 deleted_count = 1;
}

message DeleteByIdRequest {
  string id = 1;
}

message DeleteByIdResponse {
  int64 deleted_count = 1;
}

message GetAllPagedRequest {
  // how many results to return default 1000
  int32 limit = 1;
  // where to begin page default 0
  int32 offset = 2;
  // how to sort results
  repeated GetAllPagedSort sort = 3;
  // when set to true the `total count` metadata will not be calculated
  // this can save some performance as count is additional query
  bool disable_total_count = 4;
  repeated Filter filters = 5;
  // when set to true the `name` value will be sent to MongoDB as regex expression
  // when set to false the `name` value will be sent to MongoDB as a literal string
  bool enable_regex = 6;
}

message GetAllPagedSort {
  // field to sort on
  string field = 1;
  // sort direction 1 | -1
  int32 value = 2;
}

message GetAllPagedResponse {
  repeated Episode documents = 1;
  Metadata metadata = 2;
}

message GetDocumentsUpdatedBetweenDatesRequest {
  // Expressed as a valid javascript Date, https://en.wikipedia.org/wiki/ISO_8601
  string updated_at_min = 1;
  // Expressed as a valid javascript Date, https://en.wikipedia.org/wiki/ISO_8601
  string updated_at_max = 2;
}

message GetByIdRequest {
  string id = 1;
  repeated string projection = 2;
}

message GetByIdResponse {
  Episode document = 1;
}

message GetByIdsRequest {
  repeated string ids = 1;
  repeated GetAllPagedSort sort = 2;
  repeated string projection = 3;
}

message GetByIdsResponse {
  repeated Episode documents = 1;
}

message GetEpisodesByClipIdRequest {
  string id = 1;
  int32 limit = 2;
  int32 offset = 3;
  repeated GetAllPagedSort sort = 4;
  repeated string projection = 5;
}

message GetEpisodesByClipIdResponse {
  repeated Episode episodes = 1;
}

message GetEpisodeIdsBySeriesIdsRequest {
  repeated string ids = 1;
  string distinct = 2;
}

message GetEpisodeIdsBySeriesIdsResponse {
  repeated string ids = 1;
}

message Episode {
  string id = 1;
  string created_at = 2;
  string updated_at = 3;
  string name = 4;
  string display_name = 5;
  string display_on_guide = 6;
  bool ad_free = 7;
  bool ad_pods_verified = 8;
  string author = 9;
  string slug = 10;
  string uid = 11;
  int32 number = 12;
  string series = 13;
  int32 season = 14;
  int32 duration = 15;
  int32 allotment = 16;
  int32 ad_pods_duration = 17;
  string description = 18;
  string summary = 19;
  string notes = 20;
  string category = 21;
  string sub_category = 22;
  string genre = 23;
  string sub_genre = 24;
  repeated string tags = 25;
  bool published = 26;
  string status = 27;
  bool live_broadcast = 28;
  string premiere = 29;
  string first_aired = 30;
  string last_aired = 31;
  NextTimeline next_timeline = 32;
  bool derivative = 33;
  bool is_feed = 34;
  repeated string feeds = 35;
  bool featured = 36;
  string parent = 37;
  repeated Content content = 38;
  repeated Source sources = 39;
  repeated Backups backups = 40;
  repeated string channels = 41;
  Image thumbnail = 42;
  Image featured_image = 43;
  Image partner_logo = 44;
  Image poster = 45;
  Image screenshot16_9 = 46 [json_name = "screenshot16_9"];
  Image screenshot4_3 = 47 [json_name = "screenshot4_3"];
  Meta meta = 48;
  bool flagged = 49;
  DistributeAs distribute_as = 50;
  PlaybackRestrictions playback_restrictions = 51;
  repeated string vod_category_entries = 52;
  bool pluto_tv_o_o = 53;
  string tmsid = 54;
  string active_region = 55; // not in schema
  AvailabilityWindows availability_windows = 56; // not in schema
  string metadata_language = 57; // not in schema
  string rating = 58; // not in schema
  repeated string region_filter = 59;
  bool dash_enabled = 60;
  repeated string age_range = 61;
  string content_u_u_i_d = 62;
  Image poster16_9 = 63 [json_name = "poster16_9"];
  repeated CustomReferenceValue custom_references = 64;
  repeated string rating_descriptors = 65;
  // mongoose internal revision number; only generated when inserted via mongoose
  int64 v = 66;
  repeated ExternalId external_ids = 67;
  bool highlight = 68;
}

message CustomReferenceValue {
  string id = 1;
  string type = 2;
  string value = 3;
}

message AvailabilityWindows {
  repeated Window _a_v_o_d = 1 [json_name = "AVOD"];
  repeated Window linear = 2;
}

message Window {
  string start_date = 1;
  string end_date = 2;
  string id = 3;
  int32 current_screenings = 4;
  int32 screenings = 5;
}

message NextTimeline {
  string id = 1;
  string channel = 2;
  string start = 3;
}

message Content {
  string clip = 1;
  int32 in_point = 2;
  int32 out_point = 3;
  repeated AdPod ad_pods = 4;
}
message SourceDetails {
  ClipDetails clip = 2;

  int32 in_point = 3;
  int32 out_point = 4;
  repeated AdPod ad_pods = 5;
  repeated AlternativeAdPods alternative_ad_pods = 6;
}

message ClipDetails {
  string content_status = 1;
  Author author = 2;
}

message Source {
  string clip = 1;
  int32 in_point = 2;
  int32 out_point = 3;
  repeated AdPod ad_pods = 4;
  repeated AlternativeAdPods alternative_ad_pods = 5;
}

message Backups {
  string clip = 1;
  int32 in_point = 2;
  int32 out_point = 3;
}

message AdPod {
  int32 start_at = 1;
  int32 duration = 2;
  string pod_type = 3;
  bool partner_provided = 4;
  repeated string tags = 5;
  bool duration_locked = 6;
  bool verified = 7;
}

message AlternativeAdPods {
  string name = 1;
  repeated AdPod ad_pods = 2;
}

message Image {
  string path = 1;
  string title = 2;
}

message Meta {
  int32 views = 1;
}

message DistributeAs {
  bool _t_v_o_d = 1 [json_name = "TVOD"];
  bool _a_v_o_d = 2 [json_name = "AVOD"];
  bool _s_v_o_d = 3 [json_name = "SVOD"];
  bool linear = 4;
}

message PlaybackRestrictions {
  Restriction _v_o_d = 1 [json_name = "VOD"];
  Restriction linear = 2;
}

message Restriction {
  bool start_over = 1;
  bool pause = 2;
  bool fast_forward = 3;
  bool rewind = 4;
}

message GetEpisodeByIdRequest {
  string id = 1;
}

message GetAgeRangePopulatedEpisodeByIdRequest {
  string id = 1;
  repeated string projection = 2;
}

message GetAgeRangePopulatedEpisodeByIdResponse {
  AgeRangeEpisode document = 1;
}

message GetAgeRangePopulatedEpisodesByIdsRequest {
  repeated string ids = 1;
  repeated GetAllPagedSort sort = 2;
}

message GetAgeRangePopulatedEpisodesByIdsResponse {
  repeated AgeRangeEpisode documents = 1;
}

message AgeRangeEpisode {
  string id = 1;
  string created_at = 2;
  string updated_at = 3;
  string name = 4;
  string display_name = 5;
  string display_on_guide = 6;
  bool ad_free = 7;
  bool ad_pods_verified = 8;
  string author = 9;
  string slug = 10;
  string uid = 11;
  int32 number = 12;
  string series = 13;
  int32 season = 14;
  int32 duration = 15;
  int32 allotment = 16;
  int32 ad_pods_duration = 17;
  string description = 18;
  string summary = 19;
  string notes = 20;
  string category = 21;
  string sub_category = 22;
  string genre = 23;
  string sub_genre = 24;
  repeated string tags = 25;
  bool published = 26;
  string status = 27;
  bool live_broadcast = 28;
  string premiere = 29;
  string first_aired = 30;
  string last_aired = 31;
  NextTimeline next_timeline = 32;
  bool derivative = 33;
  bool is_feed = 34;
  repeated string feeds = 35;
  bool featured = 36;
  string parent = 37;
  repeated Content content = 38;
  repeated Source sources = 39;
  repeated Backups backups = 40;
  repeated string channels = 41;
  Image thumbnail = 42;
  Image featured_image = 43;
  Image partner_logo = 44;
  Image poster = 45;
  Image screenshot16_9 = 46 [json_name = "screenshot16_9"];
  Image screenshot4_3 = 47 [json_name = "screenshot4_3"];
  Meta meta = 48;
  bool flagged = 49;
  DistributeAs distribute_as = 50;
  PlaybackRestrictions playback_restrictions = 51;
  repeated string vod_category_entries = 52;
  bool pluto_tv_o_o = 53;
  string tmsid = 54;
  string active_region = 55; // not in schema
  AvailabilityWindows availability_windows = 56; // not in schema
  string metadata_language = 57; // not in schema
  string rating = 58; // not in schema
  repeated string region_filter = 59;
  bool dash_enabled = 60;
  repeated AgeRange age_range = 61;
  Image poster16_9 = 62 [json_name = "poster16_9"];
  repeated CustomReference custom_references = 63;
}

message AgeRange {
  string id = 1;
  string name = 2;
  string display_name = 3;
  string country_code = 4;
  int32 min = 5;
  int32 max = 6;
}

message UpdateContentMamUniqueIdsByIdsRequest {
  repeated ObjectIdContentIdSet object_id_content_id_sets = 1;
}

message ObjectIdContentIdSet {
  string id = 1;
  string content_u_u_i_d = 2;
}

message UpdateContentMamUniqueIdsByIdsResponse {}

// Deprecated. Will be removed once client (FW IVI) no longer using
message GetEpisodeByIdResponse {
  Episode episode = 1;
}

message GetPopulatedEpisodesByClipIdRequest {
  string id = 1;
  int32 limit = 2;
  int32 offset = 3;
  repeated GetAllPagedSort sort = 4;
  Query query = 5;
}

message Query {
  repeated Filter filter = 1;
}

message Filter {
  // field to filter on
  string field = 1;
  // value for the filter
  string value = 2;
  // type of the filter string (default), number, bool
  string type = 3;
  optional string operator = 4;
}

message PopulatePath {
  string path = 1;
  PopulatePath populate = 2;
}

message GetPopulatedEpisodeByIdRequest {
  string id = 1;
  // optional path population mapped to query
  // allowed values:
  //    series,ageRange,parent,content.clip,sources.clip,backups.clip,channels,nextTimeline._id,nextTimeline.channel,
  //    { path: 'vodCategoryEntries', populate: { path: 'vodCategory' } }
  //   { path: 'customReferences', populate: { path: 'value' } }
  repeated PopulatePath populate = 2;
  repeated string projection = 3;
}

message GetPopulatedEpisodeByIdResponse {
  EpisodePopulated episode = 1;
}

message GetPopulatedEpisodesByClipIdResponse {
  EpisodeResponse episodes = 1;
}

message Metadata {
  int32 current_offset = 1;
  int32 total_items = 2;
}

message EpisodeResponse {
  Metadata metadata = 1;
  repeated EpisodePopulated data = 2;
}

message EpisodePopulated {
  string id = 1;
  string created_at = 2;
  string updated_at = 3;
  string name = 4;
  string display_name = 5;
  string display_on_guide = 6;
  bool ad_free = 7;
  bool ad_pods_verified = 8;
  string author = 9;
  string slug = 10;
  string uid = 11;
  int32 number = 12;
  Series series = 13;
  int32 season = 14;
  int32 duration = 15;
  int32 allotment = 16;
  int32 ad_pods_duration = 17;
  string description = 18;
  string summary = 19;
  string notes = 20;
  string category = 21;
  string sub_category = 22;
  string genre = 23;
  string sub_genre = 24;
  repeated string tags = 25;
  bool published = 26;
  string status = 27;
  bool live_broadcast = 28;
  string premiere = 29;
  string first_aired = 30;
  string last_aired = 31;
  NextTimelinePopulated next_timeline = 32;
  bool derivative = 33;
  bool is_feed = 34;
  repeated string feeds = 35;
  bool featured = 36;
  Episode parent = 37;
  repeated ContentPopulated content = 38;
  repeated SourcePopulated sources = 39;
  repeated BackupsPopulated backups = 40;
  repeated Channel channels = 41;
  Image thumbnail = 42;
  Image featured_image = 43;
  Image partner_logo = 44;
  Image poster = 45;
  Image screenshot16_9 = 46 [json_name = "screenshot16_9"];
  Image screenshot4_3 = 47 [json_name = "screenshot4_3"];
  Meta meta = 48;
  bool flagged = 49;
  DistributeAs distribute_as = 50;
  PlaybackRestrictions playback_restrictions = 51;
  repeated VodCategoryEntry vod_category_entries = 52;
  bool pluto_tv_o_o = 53;
  string tmsid = 54;
  string active_region = 55; // not in schema
  AvailabilityWindows availability_windows = 56; // not in schema
  string metadata_language = 57; // not in schema
  string rating = 58; // not in schema
  repeated string region_filter = 59;
  bool dash_enabled = 60;
  repeated AgeRange age_range = 61;
  string content_u_u_i_d = 62;
  Image poster16_9 = 63 [json_name = "poster16_9"];
  repeated CustomReference custom_references = 64;
  repeated string rating_descriptors = 65;
  // mongoose internal revision number; only generated when inserted via mongoose
  int64 v = 66;
  repeated ExternalId external_ids = 67;
}

message VodCategory {
  string id = 1;
  string name = 2;
  string display_name = 3;
  int32 order = 4;
  bool enabled = 5;
  bool pluto_office_only = 6;
  string enabled_at = 7;
  string description = 8;
  RegionFilter region_filter = 9;
  RegionFilter distribution = 10;
  string intile_channel = 11;
  int32 intile_order = 12;
  Path icon_svg = 13;
  Path icon_png = 14;
  Path image_featured = 15;
  string created_at = 16;
  string updated_at = 17;
  string disabled_at = 18;
  string active_region = 19;
  bool kids_mode = 20;
  repeated Category categories = 21;
  repeated CustomReference custom_references = 22;
  bool archived = 23;
  bool hero_carousel = 24;

  message Path {
    string path = 1;
  }

  message RegionFilter {
    repeated string include = 1;
    repeated string exclude = 2;
  }

  message CustomReference {
    string id = 1;
    string type = 2;
    string value = 3;
  }
}

message CustomReference {
  string id = 1;
  string type = 2;
  Partner value = 3;
}

message Partner {
  string id = 1;
  string name = 2;
}

message VodCategoryEntry {
  string id = 1;
  VodCategory vod_category = 2;
  string episode = 3;
  string series = 4;
  int32 order = 5;
  string created_at = 6;
  string updated_at = 7;
}

message NextTimelinePopulated {
  Timeline id = 1;
  Channel channel = 2;
  string start = 3;
}

message Timeline {
  string id = 1;
  string created_at = 2;
  string updated_at = 3;
  string start = 4;
  string stop = 5;
  string episode = 6;
  string channel = 7;
  bool featured = 8;
}

message Channel {
  string id = 1;
  string created_at = 2;
  string updated_at = 3;
  string name = 4;
  string author = 5;
  string parent = 6;
  string hash = 7;
  int32 number = 8;
  int32 cohort_mask = 9;
  int32 access_code = 10;
  bool published = 11;
  string description = 12;
  string category = 13;
  repeated Category categories = 14;
  bool auto_schedule = 15;
  int32 auto_schedule_days = 16;
  string summary = 17;
  repeated string tags = 18;
  repeated string geo_targets = 19;
  bool kids_mode = 20;
  int32 featured = 21;
  string created = 22;
  string updated = 23;
  string visibility = 24;
  Image thumbnail = 25;
  Image featured_image = 26;
  Image partner_logo = 27;
  Image logo = 28;
  Image tile = 29;
  Image tile_grayscale = 30;
  Image browse = 31;
  Image background = 32;
  string notes = 33;
  string type = 34;
  string start = 35;
  string stop = 36;
  int32 redirect = 37;
  bool on_demand = 38;
  string on_demand_description = 39;
  bool archived = 40;
  string slug = 41;
  RegionFilter region_filter = 42;
  repeated int32 dma_distribution = 43;
  RegionFilter distribution = 44;
  repeated EpisodesQueue episodes_queue = 45;
  repeated string overlays = 46;
  bool direct_only = 47;
  bool live_broadcast = 48;
  bool has_sub_clips = 49;
  bool is_stitched = 50;
  bool render_interstitials = 51;
  bool pluto_office_only = 52;
  PrivateChannel private_channel = 53;
  ScheduledPublishing scheduled_publishing = 54;
  Image solid_logo_p_n_g = 55;
  Image color_logo_p_n_g = 56;
  Image solid_logo_s_v_g = 57;
  Image color_logo_s_v_g = 58;
  repeated string supported_channel_caption_languages = 59;
  string tmsid = 60;
  string active_region = 61; // not found in inf-lib-schemas
  int32 category_mask = 62; // not found in inf-lib-schemas
  string metadata_language = 63; // not found in inf-lib-schemas
  repeated string seo_aliases = 64;
  Image thumbnail_alt = 65;
  Image featured_image_alt = 66;
  Image logo_alt = 67;
  Image solid_logo_p_n_g_alt = 68;
  Image color_logo_p_n_g_alt = 69;
  Image solid_logo_s_v_g_alt = 70;
  Image color_logo_s_v_g_alt = 71;
}

message ScheduledPublishing {
  string start = 1;
  string end = 2;
  bool active = 3;
}

message PrivateChannel {
  string created_by = 1;
  string subscriber_code = 2;
  string publisher_code = 3;
  string endpoint = 4;
  string stream_name = 5;
  string episode = 6;
  string series = 7;
  string clip = 8;
  string episode_name = 9;
  string subscriber_count = 10;
}

message EpisodesQueue {
  string episode = 1;
  int32 order = 2;
}

message RegionFilter {
  repeated string include = 1;
  repeated string exclude = 2;
}

message Category {
  string cat_id = 1;
  int32 order = 2;
}
message Series {
  string id = 1;
  string updated_at = 2;
  string created_at = 3;
  string name = 4;
  bool published = 5;
  string display_name = 6;
  string slug = 7;
  repeated Season seasons = 8;
  repeated string channels = 9;
  string type = 10;
  string category = 11;
  string sub_category = 12;
  string genre = 13;
  string sub_genre = 14;
  repeated string tags = 15;
  string summary = 16;
  string description = 17;
  string notes = 18;
  Image thumbnail = 19;
  Image featured_image = 20;
  Image partner_logo = 21;
  Image poster = 22;
  Image tile = 23;
  int32 episode_count = 24;
  int32 season_count = 25;
  bool user_generated = 26;
  DistributeAs distribute_as = 27;
  repeated string vod_category_entries = 28;
  bool pluto_tv_o_o = 29;
  string tmsid = 30;
  string active_region = 31; // not in schema
  string metadata_language = 32; // not in schema
  repeated string region_filter = 33; // not in schema
  string rating = 34; // not in schema
  AvailabilityWindows availability_windows = 35; // not in schema
  string available_date = 36; // not in schema
  string expiration_date = 37; // not in schema
  bool expiration_set_manually = 38; // not in schema
  string content_u_u_i_d = 39;
  repeated string seo_aliases = 40;
  Image poster16_9 = 41 [json_name = "poster16_9"];
}

message Season {
  int32 number = 1;
  string synopsis = 2;
}

message Clip {
  reserved 54 to 56; // framerate attrs originally had int32 and need to be double. No services are using 54-56 yet, can reserve.

  string id = 1;
  string name = 2;
  string partner = 3;
  string description = 4;
  Author author = 5;
  Advertising advertising = 6;
  Image featured_image = 7;
  string thumbnail = 8;
  repeated Thumbnail thumbnails = 9;
  string pluto_avails_i_d = 10;
  bool published = 11;
  bool live_broadcast = 12;
  bool promotional = 13;
  string provider = 14;
  string code = 15;
  string partner_code = 16;
  string internal_code = 17;
  string md5 = 18;
  string url = 19;
  repeated Fragment fragments = 20;
  double in_point = 21;
  double out_point = 22;
  string type = 23;
  repeated string tags = 24;
  int32 score = 25;
  int32 votes = 26;
  string uploaded = 27;
  string updated = 28;
  Meta meta = 29;
  bool flagged = 30;
  bool captions_required = 31;
  string captioned = 32;
  repeated Cc cc = 33;
  string copyright = 34;
  string language = 35;
  string rating_reason = 36;
  string original_release_date = 37;
  string genre = 38;
  string sub_genre = 39;
  string summary = 40;
  repeated Cc subtitles = 41;
  repeated string directors = 42;
  repeated string actors = 43;
  repeated string writers = 44;
  repeated string producers = 45;
  repeated int32 breakpoints = 46 [packed = true];
  repeated string breakpoints_s_m_p_t_e = 47;
  repeated string breakpoints_ingestion = 48;
  DistributeAs distribute_as = 49;
  string programming_type = 50;
  string color = 51;
  string category = 52;
  string ad_sparx_stream_id = 53;
  string tmsid = 57;
  string created_at = 58;
  string updated_at = 59;
  repeated Source sources = 60;
  string rating = 61;
  double duration = 62;
  Origin origin = 63;
  repeated Transcode transcodes = 64;
  string active_region = 65;

  string content_status = 66; // not found in inf-lib-schemas
  repeated string region_filter = 67; // not found in inf-lib-schemas
  AvailabilityWindows availability_windows = 68; // not found in inf-lib-schemas
  string encoding_profile = 69; // not found in inf-lib-schemas
  string content_u_u_i_d = 70; // not found in inf-lib-schemas

  // work around for migrating attributes originally created with the incorrect datatype
  // ARCH-2221: validate framerate, ffprobeFramerate, feedFramerate is Double
  double framerate = 71;
  // work around for migrating attributes originally created with the incorrect datatype
  // ARCH-2221: validate framerate, ffprobeFramerate, feedFramerate is Double
  double ffprobe_framerate = 72;
  // work around for migrating attributes originally created with the incorrect datatype
  // ARCH-2221: validate framerate, ffprobeFramerate, feedFramerate is Double
  double feed_framerate = 73;

  repeated Markup markups = 74;
  repeated TimedText timed_text = 75;
  repeated string production_company = 76;
  repeated string production_countries = 77;
  int32 production_year = 78;
}

message TimedText {
  string id = 1;
  string type = 2;
  string language = 3;
  string updated_at = 4;
}

message Markup {
  string id = 1;
  string type = 2;
  int32 start = 3;
  int32 end = 4;
}

message Transcode {
  string finished_at = 1;
  string external_i_d = 2;
  string transcoder_name = 3;
  string transcode_mode = 4;
  string id = 5;
  //repeated Output outputs = 6; deprecated
  reserved 6;
  string state = 7; // not found in inf-lib-schemas
  repeated Output output = 8;
  string lib_version = 9;
  string transcoder_version = 10;
  EncryptionParams encryption_params = 11;
}

message EncryptionParams {
  string schema = 1;
  int32 rotation_interval = 2;
  string key_file_name = 3;
}

message Output {
  string url = 1;
  string type = 2;
  string id = 3;
  Dimensions dimensions = 4;
}

message Dimensions {
  int32 width = 1;
  int32 height = 2;
}

message Origin {
  string url = 1;
  string src_url = 2;
  string type = 3; /// options: 'MP4', 'WebM', 'FLV', 'HLS', 'DASH', 'RTMP', 'MOV', 'video/mp4', 'video/webm', 'video/x-flv', 'application/x-mpegURL', 'application/octet-stream', 'video/mpeg', 'video/quicktime', 'video/x-msvideo', 'video/x-ms-wmv', 'binary/octet-stream',
  int32 in_point = 4; /// Used to crop video, in seconds
  int32 out_point = 5; /// Used to crop video, in seconds
  int32 bitrate = 6; /// Bitrate in kbps
  int32 duration = 7; /// Seconds
  int32 height = 8;
  int32 width = 9;
  optional int32 size = 10; /// Optional. Size in bytes,
  optional string md5 = 11; /// Optional, 32-character MD5 digest of video
  bool generatingFile = 12; /// Used to flag when the origin file is being generated by the worker-hls-to-mp4
}

message Cc {
  string uri = 1;
  string language = 2;
  bool added_to_video = 3;
  string updated_at = 4;
  string id = 5;
}

message Fragment {
  repeated int32 breakpoints = 1;
  repeated string sub_clips = 2;
}

message Thumbnail {
  string base_url = 1;
  string prefix = 2;
  int32 width = 3;
  int32 height = 4;
  string format = 5;
  int32 interval_in_frames = 6;
  int32 interval = 7;
}

message Author {
  string id = 1;
  string name = 2;
  string url = 3;
}

message Advertising {
  string client = 1;
  repeated Schedule schedule = 2;
}

message Schedule {
  string offset = 1;
  string tag = 2;
  string type = 3;
}

message ContentPopulated {
  string id = 1;
  Clip clip = 2;
  int32 in_point = 4;
  int32 out_point = 5;
  repeated AdPod ad_pods = 6;
}

message SourcePopulated {
  string id = 1;
  Clip clip = 2;
  int32 in_point = 3;
  int32 out_point = 4;
  repeated AdPod ad_pods = 5;
  repeated AlternativeAdPods alternative_ad_pods = 6;
}

message BackupsPopulated {
  string id = 1;
  Clip clip = 2;
  int32 in_point = 3;
  int32 out_point = 4;
}

// inf-lib-schemas has a hook that populates the sources after the episode is created.
message EpisodeCreate {
  string id = 1;
  string created_at = 2;
  string updated_at = 3;
  string name = 4;
  string display_name = 5;
  string display_on_guide = 6;
  bool ad_free = 7;
  bool ad_pods_verified = 8;
  string author = 9;
  string slug = 10;
  string uid = 11;
  int32 number = 12;
  string series = 13;
  int32 season = 14;
  int32 duration = 15;
  int32 allotment = 16;
  int32 ad_pods_duration = 17;
  string description = 18;
  string summary = 19;
  string notes = 20;
  string category = 21;
  string sub_category = 22;
  string genre = 23;
  string sub_genre = 24;
  repeated string tags = 25;
  bool published = 26;
  string status = 27;
  bool live_broadcast = 28;
  string premiere = 29;
  string first_aired = 30;
  string last_aired = 31;
  NextTimeline next_timeline = 32;
  bool derivative = 33;
  bool is_feed = 34;
  repeated string feeds = 35;
  bool featured = 36;
  string parent = 37;
  repeated Content content = 38;
  repeated SourcePopulated sources = 39;
  repeated Backups backups = 40;
  repeated string channels = 41;
  Image thumbnail = 42;
  Image featured_image = 43;
  Image partner_logo = 44;
  Image poster = 45;
  Image screenshot16_9 = 46 [json_name = "screenshot16_9"];
  Image screenshot4_3 = 47 [json_name = "screenshot4_3"];
  Meta meta = 48;
  bool flagged = 49;
  DistributeAs distribute_as = 50;
  PlaybackRestrictions playback_restrictions = 51;
  repeated string vod_category_entries = 52;
  bool pluto_tv_o_o = 53;
  string tmsid = 54;
  string active_region = 55; // not in schema
  AvailabilityWindows availability_windows = 56; // not in schema
  string metadata_language = 57; // not in schema
  string rating = 58; // not in schema
  repeated string region_filter = 59;
  bool dash_enabled = 60;
  repeated string age_range = 61;
  string content_u_u_i_d = 62;
  Image poster16_9 = 63 [json_name = "poster16_9"];
  repeated CustomReference custom_references = 64;
}

message SetAdPodDurationsRequest {
  Episode document = 1;
}

message CalculateTotalAdPodsDurationRequest {
  Episode document = 1;
}

message GetChannelLibraryRequest {
  string channel_id = 1;
  string name = 2;
  int64 start = 3;
  int64 end = 4;
  repeated string status = 5;
  string rating = 6;
  string genre = 7;
  int32 season = 8;
  int32 number = 9;
  string age_range = 10;
  string tmsid = 11;
  // how many results to return default 1000
  int32 limit = 12;
  // where to begin page default 0
  int32 offset = 13;
  repeated GetAllPagedSort sort = 14;
  string updated_at = 15;
}

message GetChannelLibraryResponse {
  repeated ChannelLibraryEpisode documents = 1;
  Metadata metadata = 2;
}

message ChannelLibraryEpisode {
  string id = 1;
  string name = 2;
  string rating = 3;
  int32 season = 4;
  int32 number = 5;
  repeated ChannelLibraryAgeRange age_range = 6;
  string tmsid = 7;
  int32 duration = 8;
  string last_aired = 9;
  string first_aired = 10;
  NextTimeline next_timeline = 11;
  ChannelLibraryEpisodeSeries series = 12;
  int32 allotment = 13;
  bool featured = 14;
  bool flagged = 15;
  AvailabilityWindows availability_windows = 16;
  repeated ChannelLibraryEpisodeSources sources = 17;
  string updated_at = 18;
  bool all_clips_ready = 19;
  bool is_available_now = 20;
  bool has_unique_provider = 21;
  bool has_mixed_provider_with = 22;
  bool has_clip_with_empty_sources = 23;
  bool has_linear_availability_windows = 24;
  string author = 25;
  string status = 26;
  string genre = 27;
  bool has_ad_pods = 28;
  bool published = 29;
  bool has_live_broadcast = 30;
}

message ChannelLibraryEpisodeSeries {
  string id = 1;
  string name = 2;
}

message ChannelLibraryEpisodeSources {
  ChannelLibraryEpisodeClip clip = 1;
}

message ChannelLibraryEpisodeClipAuthor {
  string name = 1;
}

message ChannelLibraryEpisodeClip {
  string id = 1;
  string content_status = 2;
  ChannelLibraryEpisodeClipAuthor author = 3;
}

message ChannelLibraryAgeRange {
  string id = 1;
  int32 min = 2;
  int32 max = 3;
  string display_name = 4;
}

message GetPopulatedEpisodesByIdsRequest {
  repeated string ids = 1;
  // optional path population mapped to query
  // allowed values:
  // series,ageRange,parent,content.clip,sources.clip,backups.clip,channels,nextTimeline._id,nextTimeline.channel,
  //   { path: 'vodCategoryEntries', populate: { path: 'vodCategory' } }
  //   { path: 'customReferences', populate: { path: 'value' } }
  repeated PopulatePath populate = 2;
}

message GetPopulatedEpisodesByIdsResponse {
  repeated EpisodePopulated episodes = 1;
}
message GetEpisodeByNameSeriesAndActiveRegionRequest {
  string name = 1;
  string series = 2;
  string active_region = 3;
}

message GetEpisodeByNameSeriesAndActiveRegionResponse {
  Episode document = 1;
}

message GetEpisodeBySeriesSeasonAndNumberRequest {
  string series = 1;
  int32 season = 2;
  int32 number = 3;
}

message GetEpisodeBySeriesSeasonAndNumberResponse {
  Episode document = 1;
}

message UnsetNextTimelineRequest {
  repeated string idsToRemove = 1;
  string channelId = 2;
  string maxStart = 3;
}

message UnsetNextTimelineResponse {
  repeated Episode episodes = 1;
}

message UpdateLastAiredRequest {
  string episode_id = 1;
}

message UpdateLastAiredResponse {
  Episode document = 1;
}
