syntax = "proto3";

package dgn;

import "google/protobuf/duration.proto";

/* Digestion is an internal service that is responsible
   for tracking the state of live ingests. Major use cases
   include: authorizing a RTMP stream and finding where to
   connect to a live stream to start a transcode */
service DigestionV1 {

  // Returning without error = a healthy service
  rpc GetHealth(HealthRequest) returns (Health);

  // Perform stream authorization and store a stream under the channel
  rpc CreateStream (StreamAuthRequest) returns (Stream);

  // Get a stream by the channel and stream (i.e. "lirik", "live")
  // this has a bit of an odd-looking url pattern - Streams are uniquely identified
  // by a channel (hash key) and a stream (range key)
  rpc GetStream (StreamRequest) returns (Stream);

  // Delete a stream from the digestion DB.
  rpc DeleteStream(StreamRequest) returns (Stream);

  // Disconnect all streams for a channel at the ingest, and delete it from digestion DB
  rpc DisconnectChannel(ChannelRequest) returns (Channel);

  // Get all streams associated with a channel
  rpc GetChannel (ChannelRequest) returns (Channel);

  // Delete all streams associated with a channel from the digestion DB.
  rpc DeleteChannel (ChannelRequest) returns (Channel);

  // Basically a scan on the streams table
  rpc AllStreams (AllStreamsRequest) returns (StreamList);

  // Update RTMP Metadata for a given stream
  rpc UpdateStreamMetadata (UpdateMetadataRequest) returns (UpdateMetadataResponse);

  // Contacts ingest over twirp to check health of a stream
  rpc CheckIngestHealth (StreamRequest) returns (CheckIngestHealthResponse);

  rpc UpdateRedundancySource (UpdateRedundancySourceRequest) returns (UpdateRedundancySourceResponse);

  // Puts arbitrary metadata into a stream.
  rpc PutIngestMetadata(PutIngestMetadataRequest) returns (PutIngestMetadataResponse);
}

// A channel contains all streams associated with that channel.
// i.e. channel = "lirik", streams = {live, backup, delay}
message Channel {
  repeated Stream streams = 1;
}

// Information surrounding which redundancy features are allowed
message RedundancyProperties {
  // Try to connect to backup streams on disconnect
  bool allow_failover_to_backup = 1;
  // Show a slate on disconnect
  google.protobuf.Duration disconnect_slate_duration = 2;
  enum SlateBrand {
    WHITE_LABEL = 0;  // generic slate
    PURPLE = 1;       // purpleish slate
  }
  SlateBrand slate_brand = 3;
}

message TranscodeStack {
	string transcode_type = 1;
	string encoder_type = 2;
}

// A stream represents a single RTMP ingest
message Stream {

  //"lirik"
  string channel = 1;

  //live, backup, delay, spanish? camera angles? mostly just live for now.
  string format = 2;

  //connect here with RTMP to pull the channel
  string RTMP_endpoint = 3;

  //make http requests to [NGST](https://git-aws.internal.justin.tv/video/goingest/tree/master/pkg/ngst/ngst.md) here to do things like make sure the stream still exists
  // string JSON_endpoint = 4;

  //dial grpc [NGST](https://git-aws.internal.justin.tv/video/goingest/tree/master/pkg/ngst/ngst.md) here to do things like make sure the stream still exists
  // string GRPC_endpoint = 5;

  //make twirp requests to [NGST](https://git-aws.internal.justin.tv/video/goingest/tree/master/pkg/ngst/ngst.md) here to do things like make sure the stream still exists
  string twirp_endpoint = 11;

  //unique sessionID tied to the broadcast. not really used for anything now.
  string sessionID  = 6;

  // url-style params that came in with the stream key
  map<string, string> params = 7;

  // whether the daemon has successfully retreived this stream recently
  bool healthy = 8;

  // unix epoch of when the stream was last successfully retreived
  int64 last_seen = 9;

  //mimicking the old usher behavior of delay_length
  uint32 delay_length = 10;

  //RTMP Metadata associated with a stream
  map<string, string> rtmp_metadata = 12;

  string channel_id = 14;

  //Client IP assosciated with the specific stream
  string client_ip = 15 ;

  // S3 bucket to be used for this broadcast
  string s3_bucket = 16;
  // The SNS ARN to be used to send notifcations for this bucket
  string sns_endpoint = 17 ;
  // The S3 prefix to be used for this broadcast
  string s3_prefix = 18;
  //This represents the time at which the stream started
  int64 start_time = 19;
  // The full rtmp Url which can be used for playback and gotranscoder to connect to
  string rtmp_url = 20;
  // The CDN url which is to be used to record static vod manifests , used for LVS streams
  string cdn_url = 21;
  // flag which specifies if we are using low latency mode here
  bool low_latency = 22;
  // number of consecutive failed health checks
  int64 failed_health_checks = 23;
  // Capabilities surrounding which redundancy features are allowed
  RedundancyProperties redundancy_properties = 24;
  //Latency mode for the broadcast, this seeting in Digestion is mainly used for LVS
  //latency mode for twitch streams are stored in channel properties
  string latency_mode = 25;

  StreamRequest redundancy_source_stream = 26;

  repeated TranscodeStack transcode_stacks = 27;

  string customer_id = 28;
  string content_id = 29;
}

message StreamAuthRequest {

  // widely referred to elsewhere as just 'stream key', i call this fullStreamKey to distinguish it from
  // just the SHA1 as web considers a streamkey
  // looks like `live_123355_aksldjfhlksdjfh` or however an authorized key looks
  // basically whatever you could put into obs as a stream key will work here
  // params will be broken into the `params`
  string fullStreamKey = 1;

  // the internal NGST/usher name for the stream, like `live_user_lirik`
  string RTMP_name = 2;

  // when authing, NGST must fill out these endpoints so that clients can pull/query the live streams
  string RTMP_endpoint = 3;

  // when authing, NGST must fill out these endpoints so that clients can pull/query the live streams
  string JSON_endpoint = 4;

  // when authing, NGST must fill out these endpoints so that clients can pull/query the live streams
  string GRPC_endpoint = 5;

  // when authing, NGST must fill out these endpoints so that clients can pull/query the live streams
  string twirp_endpoint = 6;

  string uuid = 7;

  string client_ip = 8 ;
}

// uniquely identifies a channel
message ChannelRequest {
  string channel = 1;
}

// uniquely identifies a stream
message StreamRequest {
  string channel = 1;
  string format = 2;

  // optional session_id, to ensure the correct session is specified (useful on delete)
  string sessionID = 3;
}

message HealthRequest { }
message Health {
  string info = 1;
}

// used for scanning digestion db, you must indicate what shard you are part of.
// if you just want to scan the entire db, set segment to 0 and total_segments to 1
message AllStreamsRequest {

  // which scan shard member you are
  int64 segment = 1;

  // how many scan shard members tehre are in total
  int64 total_segments = 2;
}

message StreamList {
  repeated Stream streams = 1;
}

message SetStreamHealthRequest {
  // uniquely identify a stream
  StreamRequest stream_request = 1;

  // if healthy, set healthy to true and set last_seen to now
  // otherwise, set healthy to false and dont touch last_seen
  bool healthy = 2;

  // number of consecutive failed health checks
  int64 failed_health_checks = 3;
}

message SetStreamHealthResponse {}


message UpdateMetadataRequest {
  // uniquely identify a stream
  StreamRequest stream_request = 1;
  // RTMP Metadata associated with a stream
  map<string, string> rtmp_metadata = 2;
}

message UpdateMetadataResponse {
}

message UpdateRedundancySourceRequest {
  StreamRequest stitcher = 1;
  StreamRequest source = 2;
}
message UpdateRedundancySourceResponse {
}

message CheckIngestHealthResponse {
  // The stream as found in DigestionDB
  Stream stream = 1;

  // Whether the health check succeeded
  bool ingestOK = 2;

  // True if the checked process is waiting for a reingest
  bool is_in_slate = 3;
}

message PutIngestMetadataRequest {
  // Channel name
  string channel = 1; // required
  // Metadata to insert encoded as a base64 string
  string metadata = 2; // required
  // ISO-8601 UTC time that the client requested the metadata to be inserted.
  string requested_at = 3; // required
  // SNS topic id to notify after insertion
  string sns_topic_id = 4;
  // Rate limit allowed for the stream
  uint32 rate_limit = 5; // required
}

message PutIngestMetadataResponse {
}
