// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.cloud.video.livestream.v1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/video/livestream/v1/outputs.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "google/rpc/status.proto";

option csharp_namespace = "Google.Cloud.Video.LiveStream.V1";
option go_package = "cloud.google.com/go/video/livestream/apiv1/livestreampb;livestreampb";
option java_multiple_files = true;
option java_outer_classname = "ResourcesProto";
option java_package = "com.google.cloud.video.livestream.v1";
option php_namespace = "Google\\Cloud\\Video\\LiveStream\\V1";
option ruby_package = "Google::Cloud::Video::LiveStream::V1";

// Input resource represents the endpoint from which the channel ingests
// the input stream.
message Input {
  option (google.api.resource) = {
    type: "livestream.googleapis.com/Input"
    pattern: "projects/{project}/locations/{location}/inputs/{input}"
  };

  // The type of the input.
  enum Type {
    // Input type is not specified.
    TYPE_UNSPECIFIED = 0;

    // Input will take an rtmp input stream.
    RTMP_PUSH = 1;

    // Input will take an srt (Secure Reliable Transport) input stream.
    SRT_PUSH = 2;
  }

  // Tier of the input specification.
  enum Tier {
    // Tier is not specified.
    TIER_UNSPECIFIED = 0;

    // Resolution < 1280x720. Bitrate <= 6 Mbps. FPS <= 60.
    SD = 1;

    // Resolution <= 1920x1080. Bitrate <= 25 Mbps. FPS <= 60.
    HD = 2;

    // Resolution <= 4096x2160. Not supported yet.
    UHD = 3;
  }

  // Security rules for access control. Each field represents one security rule.
  // Only when the source of the input stream satisfies all the fields, this
  // input stream can be accepted.
  message SecurityRule {
    // At least one ip range must match unless none specified. The IP range is
    // defined by CIDR block: for example, `192.0.1.0/24` for a range and
    // `192.0.1.0/32` for a single IP address.
    repeated string ip_ranges = 1;
  }

  // The resource name of the input, in the form of:
  // `projects/{project}/locations/{location}/inputs/{inputId}`.
  string name = 1;

  // Output only. The creation time.
  google.protobuf.Timestamp create_time = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The update time.
  google.protobuf.Timestamp update_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // User-defined key/value metadata.
  map<string, string> labels = 4;

  // Source type.
  Type type = 5;

  // Tier defines the maximum input specification that is accepted by the
  // video pipeline. The billing is charged based on the tier specified here.
  // See [Pricing](https://cloud.google.com/livestream/pricing) for more detail.
  // The default is `HD`.
  Tier tier = 14;

  // Output only. URI to push the input stream to.
  // Its format depends on the input
  // [type][google.cloud.video.livestream.v1.Input.type], for example:
  //
  // *  `RTMP_PUSH`: `rtmp://1.2.3.4/live/{STREAM-ID}`
  // *  `SRT_PUSH`: `srt://1.2.3.4:4201?streamid={STREAM-ID}`
  string uri = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Preprocessing configurations.
  PreprocessingConfig preprocessing_config = 9;

  // Security rule for access control.
  SecurityRule security_rules = 12;

  // Output only. The information for the input stream. This field will be
  // present only when this input receives the input stream.
  InputStreamProperty input_stream_property = 15
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Channel resource represents the processor that does a user-defined
// "streaming" operation, which includes getting an input stream through an
// input, transcoding it to multiple renditions, and publishing output live
// streams in certain formats (for example, HLS or DASH) to the specified
// location.
message Channel {
  option (google.api.resource) = {
    type: "livestream.googleapis.com/Channel"
    pattern: "projects/{project}/locations/{location}/channels/{channel}"
  };

  // Location of output file(s) in a Google Cloud Storage bucket.
  message Output {
    // URI for the output file(s). For example, `gs://my-bucket/outputs/`.
    string uri = 1;
  }

  // State of streaming operation that the channel is running.
  enum StreamingState {
    // Streaming state is not specified.
    STREAMING_STATE_UNSPECIFIED = 0;

    // Channel is getting the input stream, generating the live streams to the
    // specified output location.
    STREAMING = 1;

    // Channel is waiting for the input stream through the input.
    AWAITING_INPUT = 2;

    // Channel is running, but has trouble publishing the live streams onto the
    // specified output location (for example, the specified Cloud Storage
    // bucket is not writable).
    STREAMING_ERROR = 4;

    // Channel is generating live streams with no input stream. Live streams are
    // filled out with black screen, while input stream is missing.
    // Not supported yet.
    STREAMING_NO_INPUT = 5;

    // Channel is stopped, finishing live streams.
    STOPPED = 6;

    // Channel is starting.
    STARTING = 7;

    // Channel is stopping.
    STOPPING = 8;
  }

  // The resource name of the channel, in the form of:
  // `projects/{project}/locations/{location}/channels/{channelId}`.
  string name = 1;

  // Output only. The creation time.
  google.protobuf.Timestamp create_time = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The update time.
  google.protobuf.Timestamp update_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // User-defined key/value metadata.
  map<string, string> labels = 4;

  // A list of input attachments that this channel uses.
  // One channel can have multiple inputs as the input sources. Only one
  // input can be selected as the input source at one time.
  repeated InputAttachment input_attachments = 16;

  // Output only. The
  // [InputAttachment.key][google.cloud.video.livestream.v1.InputAttachment.key]
  // that serves as the current input source. The first input in the
  // [input_attachments][google.cloud.video.livestream.v1.Channel.input_attachments]
  // is the initial input source.
  string active_input = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Required. Information about the output (that is, the Cloud Storage bucket
  // to store the generated live stream).
  Output output = 9 [(google.api.field_behavior) = REQUIRED];

  // List of elementary streams.
  repeated ElementaryStream elementary_streams = 10;

  // List of multiplexing settings for output streams.
  repeated MuxStream mux_streams = 11;

  // List of output manifests.
  repeated Manifest manifests = 12;

  // List of output sprite sheets.
  repeated SpriteSheet sprite_sheets = 13;

  // Output only. State of the streaming operation.
  StreamingState streaming_state = 14
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. A description of the reason for the streaming error. This
  // property is always present when
  // [streaming_state][google.cloud.video.livestream.v1.Channel.streaming_state]
  // is
  // [STREAMING_ERROR][google.cloud.video.livestream.v1.Channel.StreamingState.STREAMING_ERROR].
  google.rpc.Status streaming_error = 18
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Configuration of platform logs for this channel.
  LogConfig log_config = 19;

  // Configuration of timecode for this channel.
  TimecodeConfig timecode_config = 21;

  // Encryption configurations for this channel. Each configuration has an ID
  // which is referred to by each MuxStream to indicate which configuration is
  // used for that output.
  repeated Encryption encryptions = 24;

  // The configuration for input sources defined in
  // [input_attachments][google.cloud.video.livestream.v1.Channel.input_attachments].
  InputConfig input_config = 25;
}

// Configuration for the input sources of a channel.
message InputConfig {
  // Input switch mode.
  enum InputSwitchMode {
    // The input switch mode is not specified.
    INPUT_SWITCH_MODE_UNSPECIFIED = 0;

    // Automatic failover is enabled. The primary input stream is always
    // preferred over its backup input streams configured using the
    // [AutomaticFailover][google.cloud.video.livestream.v1.InputAttachment.AutomaticFailover]
    // field.
    FAILOVER_PREFER_PRIMARY = 1;

    // Automatic failover is disabled. You must use the
    // [inputSwitch][google.cloud.video.livestream.v1.Event.input_switch] event
    // to switch the active input source for the channel to stream from. When
    // this mode is chosen, the
    // [AutomaticFailover][google.cloud.video.livestream.v1.InputAttachment.AutomaticFailover]
    // field is ignored.
    MANUAL = 3;
  }

  // Input switch mode. Default mode is `FAILOVER_PREFER_PRIMARY`.
  InputSwitchMode input_switch_mode = 1;
}

// Configuration of platform logs.
// See [Using and managing platform
// logs](https://cloud.google.com/logging/docs/api/platform-logs#managing-logs)
// for more information about how to view platform logs through Cloud Logging.
message LogConfig {
  // The severity level of platform logging for this channel. Logs with a
  // severity level higher than or equal to the chosen severity level will be
  // logged and can be viewed through Cloud Logging.
  // The severity level of a log is ranked as followed from low to high: DEBUG <
  // INFO < NOTICE < WARNING < ERROR < CRITICAL < ALERT < EMERGENCY.
  // See
  // [LogSeverity](https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#logseverity)
  // for more information.
  enum LogSeverity {
    // Log severity is not specified. This is the same as log severity is OFF.
    LOG_SEVERITY_UNSPECIFIED = 0;

    // Log is turned off.
    OFF = 1;

    // Log with severity higher than or equal to DEBUG are logged.
    DEBUG = 100;

    // Logs with severity higher than or equal to INFO are logged.
    INFO = 200;

    // Logs with severity higher than or equal to WARNING are logged.
    WARNING = 400;

    // Logs with severity higher than or equal to ERROR are logged.
    ERROR = 500;
  }

  // The severity level of platform logging for this resource.
  LogSeverity log_severity = 1;
}

// Properties of the input stream.
message InputStreamProperty {
  // The time that the current input stream is accepted and the connection is
  // established.
  google.protobuf.Timestamp last_establish_time = 1;

  // Properties of the video streams.
  repeated VideoStreamProperty video_streams = 2;

  // Properties of the audio streams.
  repeated AudioStreamProperty audio_streams = 3;
}

// Properties of the video stream.
message VideoStreamProperty {
  // Index of this video stream.
  int32 index = 1;

  // Properties of the video format.
  VideoFormat video_format = 2;
}

// Properties of the video format.
message VideoFormat {
  // Video codec used in this video stream.
  string codec = 1;

  // The width of the video stream in pixels.
  int32 width_pixels = 2;

  // The height of the video stream in pixels.
  int32 height_pixels = 3;

  // The frame rate of the input video stream.
  double frame_rate = 4;
}

// Properties of the audio stream.
message AudioStreamProperty {
  // Index of this audio stream.
  int32 index = 1;

  // Properties of the audio format.
  AudioFormat audio_format = 2;
}

// Properties of the audio format.
message AudioFormat {
  // Audio codec used in this audio stream.
  string codec = 1;

  // The number of audio channels.
  int32 channel_count = 2;

  // A list of channel names specifying the layout of the audio channels.
  repeated string channel_layout = 3;
}

// A group of information for attaching an input resource to this channel.
message InputAttachment {
  // Configurations to follow when automatic failover happens.
  message AutomaticFailover {
    // The
    // [InputAttachment.key][google.cloud.video.livestream.v1.InputAttachment.key]s
    // of inputs to failover to when this input is disconnected. Currently, only
    // up to one backup input is supported.
    repeated string input_keys = 1;
  }

  // A unique key for this input attachment.
  string key = 1;

  // The resource name of an existing input, in the form of:
  // `projects/{project}/locations/{location}/inputs/{inputId}`.
  string input = 2 [(google.api.resource_reference) = {
    type: "livestream.googleapis.com/Input"
  }];

  // Automatic failover configurations.
  AutomaticFailover automatic_failover = 3;
}

// Event is a sub-resource of a channel, which can be scheduled by the user to
// execute operations on a channel resource without having to stop the channel.
message Event {
  option (google.api.resource) = {
    type: "livestream.googleapis.com/Event"
    pattern: "projects/{project}/locations/{location}/channels/{channel}/events/{event}"
  };

  // Switches to another input stream. Automatic failover is then disabled.
  message InputSwitchTask {
    // The
    // [InputAttachment.key][google.cloud.video.livestream.v1.InputAttachment.key]
    // of the input to switch to.
    string input_key = 1;
  }

  // Inserts a new ad opportunity.
  message AdBreakTask {
    // Duration of an ad opportunity. Must be greater than 0.
    google.protobuf.Duration duration = 1;
  }

  // Inserts a slate.
  message SlateTask {
    // Optional. Duration of the slate. Must be greater than 0 if specified.
    // Omit this field for a long running slate.
    google.protobuf.Duration duration = 1;

    // Slate asset to use for the duration. If its duration is less than the
    // duration of the SlateTask, then it will be looped. The slate must be
    // represented in the form of:
    // `projects/{project}/locations/{location}/assets/{assetId}`.
    string asset = 2 [(google.api.resource_reference) = {
      type: "livestream.googleapis.com/Asset"
    }];
  }

  // Stops any events which are currently running. This only applies to events
  // with a duration.
  message ReturnToProgramTask {}

  // Mutes the stream.
  message MuteTask {
    // Duration for which the stream should be muted. If omitted, the stream
    // will be muted until an UnmuteTask event is sent.
    google.protobuf.Duration duration = 1;
  }

  // Unmutes the stream. The task will fail if the stream is not
  // currently muted.
  message UnmuteTask {}

  // State of the event
  enum State {
    // Event state is not specified.
    STATE_UNSPECIFIED = 0;

    // Event is scheduled but not executed yet.
    SCHEDULED = 1;

    // Event is being executed.
    RUNNING = 2;

    // Event has been successfully executed.
    SUCCEEDED = 3;

    // Event fails to be executed.
    FAILED = 4;

    // Event has been created but not scheduled yet.
    PENDING = 5;

    // Event was stopped before running for its full duration.
    STOPPED = 6;
  }

  // The resource name of the event, in the form of:
  // `projects/{project}/locations/{location}/channels/{channelId}/events/{eventId}`.
  string name = 1;

  // Output only. The creation time.
  google.protobuf.Timestamp create_time = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The update time.
  google.protobuf.Timestamp update_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // User-defined key/value metadata.
  map<string, string> labels = 4;

  // Required. Operation to be executed by this event.
  oneof task {
    // Switches to another input stream.
    InputSwitchTask input_switch = 5;

    // Inserts a new ad opportunity.
    AdBreakTask ad_break = 6;

    // Stops any running ad break.
    ReturnToProgramTask return_to_program = 13;

    // Inserts a slate.
    SlateTask slate = 14;

    // Mutes the stream.
    MuteTask mute = 15;

    // Unmutes the stream.
    UnmuteTask unmute = 16;
  }

  // When this field is set to true, the event will be executed at the earliest
  // time that the server can schedule the event and
  // [execution_time][google.cloud.video.livestream.v1.Event.execution_time]
  // will be populated with the time that the server actually schedules the
  // event.
  bool execute_now = 9;

  // The time to execute the event. If you set
  // [execute_now][google.cloud.video.livestream.v1.Event.execute_now] to
  // `true`, then do not set this field in the `CreateEvent` request. In
  // this case, the server schedules the event and populates this field. If you
  // set [execute_now][google.cloud.video.livestream.v1.Event.execute_now] to
  // `false`, then you must set this field to at least 10 seconds in the future
  // or else the event can't be created.
  google.protobuf.Timestamp execution_time = 10;

  // Output only. The state of the event.
  State state = 11 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. An error object that describes the reason for the failure.
  // This property is always present when `state` is `FAILED`.
  google.rpc.Status error = 12 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// An asset represents a video or an image.
message Asset {
  option (google.api.resource) = {
    type: "livestream.googleapis.com/Asset"
    pattern: "projects/{project}/locations/{location}/assets/{asset}"
  };

  // VideoAsset represents a video. The supported formats are MP4, MPEG-TS, and
  // FLV. The supported video codec is H264. The supported audio codecs are
  // AAC, AC3, MP2, and MP3.
  message VideoAsset {
    // Cloud Storage URI of the video. The format is `gs://my-bucket/my-object`.
    string uri = 1;
  }

  // Image represents an image. The supported format is JPEG.
  message ImageAsset {
    // Cloud Storage URI of the image. The format is `gs://my-bucket/my-object`.
    string uri = 1;
  }

  // State of the asset resource.
  enum State {
    // State is not specified.
    STATE_UNSPECIFIED = 0;

    // The asset is being created.
    CREATING = 1;

    // The asset is ready for use.
    ACTIVE = 2;

    // The asset is being deleted.
    DELETING = 3;

    // The asset has an error.
    ERROR = 4;
  }

  // The resource name of the asset, in the form of:
  // `projects/{project}/locations/{location}/assets/{assetId}`.
  string name = 1;

  // Output only. The creation time.
  google.protobuf.Timestamp create_time = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The update time.
  google.protobuf.Timestamp update_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // User-defined key/value metadata.
  map<string, string> labels = 4;

  // The reference to the asset.
  // The maximum size of the resource is 250 MB.
  oneof resource {
    // VideoAsset represents a video.
    VideoAsset video = 5;

    // ImageAsset represents an image.
    ImageAsset image = 6;
  }

  // Based64-encoded CRC32c checksum of the asset file. For more information,
  // see the crc32c checksum of the [Cloud Storage Objects
  // resource](https://cloud.google.com/storage/docs/json_api/v1/objects).
  // If crc32c is omitted or left empty when the asset is created, this field is
  // filled by the crc32c checksum of the Cloud Storage object indicated by
  // [VideoAsset.uri] or [ImageAsset.uri].
  // If crc32c is set, the asset can't be created if the crc32c value does not
  // match with the crc32c checksum of the Cloud Storage object indicated by
  // [VideoAsset.uri] or [ImageAsset.uri].
  string crc32c = 7;

  // Output only. The state of the asset resource.
  State state = 8 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Only present when `state` is `ERROR`. The reason for the error
  // state of the asset.
  google.rpc.Status error = 9 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Encryption settings.
message Encryption {
  // Configuration for secrets stored in Google Secret Manager.
  message SecretManagerSource {
    // Required. The name of the Secret Version containing the encryption key.
    // `projects/{project}/secrets/{secret_id}/versions/{version_number}`
    string secret_version = 1 [
      (google.api.field_behavior) = REQUIRED,
      (google.api.resource_reference) = {
        type: "secretmanager.googleapis.com/SecretVersion"
      }
    ];
  }

  // Widevine configuration.
  message Widevine {}

  // Fairplay configuration.
  message Fairplay {}

  // Playready configuration.
  message Playready {}

  // Clearkey configuration.
  message Clearkey {}

  // Defines configuration for DRM systems in use. If a field is omitted,
  // that DRM system will be considered to be disabled.
  message DrmSystems {
    // Widevine configuration.
    Widevine widevine = 1;

    // Fairplay configuration.
    Fairplay fairplay = 2;

    // Playready configuration.
    Playready playready = 3;

    // Clearkey configuration.
    Clearkey clearkey = 4;
  }

  // Configuration for HLS AES-128 encryption.
  message Aes128Encryption {}

  // Configuration for HLS SAMPLE-AES encryption.
  message SampleAesEncryption {}

  // Configuration for MPEG-Dash Common Encryption (MPEG-CENC).
  message MpegCommonEncryption {
    // Required. Specify the encryption scheme, supported schemes:
    // - `cenc` - AES-CTR subsample
    // - `cbcs`- AES-CBC subsample pattern
    string scheme = 1 [(google.api.field_behavior) = REQUIRED];
  }

  // Required. Identifier for this set of encryption options.
  string id = 1 [(google.api.field_behavior) = REQUIRED];

  // Defines where content keys are stored.
  oneof secret_source {
    // For keys stored in Google Secret Manager.
    SecretManagerSource secret_manager_key_source = 7;
  }

  // Required. Configuration for DRM systems.
  DrmSystems drm_systems = 3 [(google.api.field_behavior) = REQUIRED];

  // Encryption modes for HLS and MPEG-Dash.
  oneof encryption_mode {
    // Configuration for HLS AES-128 encryption.
    Aes128Encryption aes128 = 4;

    // Configuration for HLS SAMPLE-AES encryption.
    SampleAesEncryption sample_aes = 5;

    // Configuration for MPEG-Dash Common Encryption (MPEG-CENC).
    MpegCommonEncryption mpeg_cenc = 6;
  }
}

// Pool resource defines the configuration of Live Stream pools for a specific
// location. Currently we support only one pool resource per project per
// location. After the creation of the first input, a default pool is created
// automatically at "projects/{project}/locations/{location}/pools/default".
message Pool {
  option (google.api.resource) = {
    type: "livestream.googleapis.com/Pool"
    pattern: "projects/{project}/locations/{location}/pools/{pool}"
  };

  // Defines the network configuration for the pool.
  message NetworkConfig {
    // peered_network is the network resource URL of the network that is peered
    // to the service provider network. Must be of the format
    // projects/NETWORK_PROJECT_NUMBER/global/networks/NETWORK_NAME, where
    // NETWORK_PROJECT_NUMBER is the project number of the Cloud project that
    // holds your VPC network and NETWORK_NAME is the name of your VPC network.
    // If peered_network is omitted or empty, the pool will use endpoints that
    // are publicly available.
    string peered_network = 1 [(google.api.resource_reference) = {
      type: "compute.googleapis.com/Network"
    }];
  }

  // The resource name of the pool, in the form of:
  // `projects/{project}/locations/{location}/pools/{poolId}`.
  string name = 1;

  // Output only. The creation time.
  google.protobuf.Timestamp create_time = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The update time.
  google.protobuf.Timestamp update_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // User-defined key/value metadata.
  map<string, string> labels = 4;

  // Network configuration for the pool.
  NetworkConfig network_config = 5;
}
