syntax = "proto3";

package veza.stream;

option go_package = "veza-backend-api/proto/stream";

import "common/auth.proto";

// Service Stream pour communication avec le module Rust
service StreamService {
  // Gestion des streams
  rpc CreateStream(CreateStreamRequest) returns (CreateStreamResponse);
  rpc StartStream(StartStreamRequest) returns (StartStreamResponse);
  rpc StopStream(StopStreamRequest) returns (StopStreamResponse);
  rpc GetStreamInfo(GetStreamInfoRequest) returns (Stream);
  rpc ListActiveStreams(ListActiveStreamsRequest) returns (ListActiveStreamsResponse);
  
  // Gestion des auditeurs
  rpc JoinStream(JoinStreamRequest) returns (JoinStreamResponse);
  rpc LeaveStream(LeaveStreamRequest) returns (LeaveStreamResponse);
  rpc GetListeners(GetListenersRequest) returns (GetListenersResponse);
  
  // Contrôle audio
  rpc ChangeQuality(ChangeQualityRequest) returns (ChangeQualityResponse);
  rpc GetAudioMetrics(GetAudioMetricsRequest) returns (AudioMetrics);
  rpc SetVolume(SetVolumeRequest) returns (SetVolumeResponse);
  
  // Recording
  rpc StartRecording(StartRecordingRequest) returns (StartRecordingResponse);
  rpc StopRecording(StopRecordingRequest) returns (StopRecordingResponse);
  rpc GetRecordings(GetRecordingsRequest) returns (GetRecordingsResponse);
  
  // Analytics
  rpc GetStreamAnalytics(GetStreamAnalyticsRequest) returns (StreamAnalytics);
  rpc GetUserListeningHistory(GetUserListeningHistoryRequest) returns (UserListeningHistory);
  
  // Notifications temps réel
  rpc SubscribeToStreamEvents(SubscribeToStreamEventsRequest) returns (stream StreamEvent);
}

// Messages pour la gestion des streams
message CreateStreamRequest {
  string title = 1;
  string description = 2;
  StreamCategory category = 3;
  StreamVisibility visibility = 4;
  int64 streamer_id = 5;
  StreamQuality default_quality = 6;
  string auth_token = 7;
}

message CreateStreamResponse {
  Stream stream = 1;
  string stream_key = 2;
  string rtmp_url = 3;
  string error = 4;
}

message StartStreamRequest {
  string stream_id = 1;
  int64 streamer_id = 2;
  StreamConfig config = 3;
  string auth_token = 4;
}

message StartStreamResponse {
  bool success = 1;
  string stream_url = 2;
  repeated string hls_urls = 3; // URLs pour différentes qualités
  string error = 4;
}

message StopStreamRequest {
  string stream_id = 1;
  int64 streamer_id = 2;
  string auth_token = 3;
}

message StopStreamResponse {
  bool success = 1;
  StreamSummary summary = 2;
  string error = 3;
}

message GetStreamInfoRequest {
  string stream_id = 1;
  string auth_token = 2;
}

message ListActiveStreamsRequest {
  StreamCategory category = 1;
  int32 page = 2;
  int32 limit = 3;
  StreamSortBy sort_by = 4;
  string auth_token = 5;
}

message ListActiveStreamsResponse {
  repeated Stream streams = 1;
  int32 total = 2;
  string error = 3;
}

// Messages pour les auditeurs
message JoinStreamRequest {
  string stream_id = 1;
  int64 user_id = 2;
  StreamQuality preferred_quality = 3;
  string auth_token = 4;
}

message JoinStreamResponse {
  bool success = 1;
  string stream_url = 2;
  StreamQuality actual_quality = 3;
  int32 buffer_duration = 4; // en millisecondes
  string error = 5;
}

message LeaveStreamRequest {
  string stream_id = 1;
  int64 user_id = 2;
  string auth_token = 3;
}

message LeaveStreamResponse {
  bool success = 1;
  int64 listen_duration = 2; // en secondes
  string error = 3;
}

message GetListenersRequest {
  string stream_id = 1;
  string auth_token = 2;
}

message GetListenersResponse {
  repeated StreamListener listeners = 1;
  int32 total_count = 2;
  string error = 3;
}

// Messages pour le contrôle audio
message ChangeQualityRequest {
  string stream_id = 1;
  int64 user_id = 2;
  StreamQuality quality = 3;
  string auth_token = 4;
}

message ChangeQualityResponse {
  bool success = 1;
  string new_stream_url = 2;
  string error = 3;
}

message GetAudioMetricsRequest {
  string stream_id = 1;
  string auth_token = 2;
}

message SetVolumeRequest {
  string stream_id = 1;
  int64 user_id = 2;
  int32 volume = 3; // 0-100
  string auth_token = 4;
}

message SetVolumeResponse {
  bool success = 1;
  string error = 2;
}

// Messages pour le recording
message StartRecordingRequest {
  string stream_id = 1;
  int64 streamer_id = 2;
  RecordingConfig config = 3;
  string auth_token = 4;
}

message StartRecordingResponse {
  bool success = 1;
  string recording_id = 2;
  string error = 3;
}

message StopRecordingRequest {
  string stream_id = 1;
  string recording_id = 2;
  int64 streamer_id = 3;
  string auth_token = 4;
}

message StopRecordingResponse {
  bool success = 1;
  Recording recording = 2;
  string error = 3;
}

message GetRecordingsRequest {
  int64 streamer_id = 1;
  int32 page = 2;
  int32 limit = 3;
  string auth_token = 4;
}

message GetRecordingsResponse {
  repeated Recording recordings = 1;
  int32 total = 2;
  string error = 3;
}

// Messages pour les analytics
message GetStreamAnalyticsRequest {
  string stream_id = 1;
  int64 start_time = 2;
  int64 end_time = 3;
  string auth_token = 4;
}

message GetUserListeningHistoryRequest {
  int64 user_id = 1;
  int32 limit = 2;
  string auth_token = 3;
}

message SubscribeToStreamEventsRequest {
  string stream_id = 1;
  repeated StreamEventType event_types = 2;
  string auth_token = 3;
}

// Types de données
message Stream {
  string id = 1;
  string title = 2;
  string description = 3;
  StreamCategory category = 4;
  StreamVisibility visibility = 5;
  int64 streamer_id = 6;
  string streamer_username = 7;
  StreamStatus status = 8;
  StreamQuality current_quality = 9;
  int32 listener_count = 10;
  int64 created_at = 11;
  int64 started_at = 12;
  int64 duration = 13; // en secondes
  bool is_recording = 14;
  StreamMetadata metadata = 15;
}

message StreamConfig {
  StreamQuality quality = 1;
  int32 bitrate = 2; // kbps
  int32 sample_rate = 3; // Hz
  AudioCodec codec = 4;
  bool enable_recording = 5;
  bool enable_chat = 6;
  int32 max_listeners = 7;
}

message StreamListener {
  int64 user_id = 1;
  string username = 2;
  StreamQuality current_quality = 3;
  int64 joined_at = 4;
  int64 listen_duration = 5;
  bool is_active = 6;
  string location = 7; // géolocalisation
}

message StreamSummary {
  string stream_id = 1;
  int64 total_duration = 2;
  int32 max_listeners = 3;
  int32 unique_listeners = 4;
  int64 total_listen_time = 5;
  float average_listen_duration = 6;
}

message AudioMetrics {
  string stream_id = 1;
  int32 current_bitrate = 2;
  int32 buffer_health = 3; // %
  float latency = 4; // millisecondes
  int32 dropped_frames = 5;
  QualityStats quality_stats = 6;
  int64 measured_at = 7;
}

message QualityStats {
  map<string, int32> quality_distribution = 1; // qualité -> nombre d'auditeurs
  float average_buffer_duration = 2;
  int32 rebuffer_events = 3;
}

message Recording {
  string id = 1;
  string stream_id = 2;
  string title = 3;
  int64 duration = 4;
  int64 file_size = 5; // bytes
  StreamQuality quality = 6;
  AudioCodec codec = 7;
  string file_url = 8;
  string thumbnail_url = 9;
  int64 created_at = 10;
  RecordingStatus status = 11;
}

message RecordingConfig {
  StreamQuality quality = 1;
  AudioCodec codec = 2;
  bool auto_upload = 3;
  string title = 4;
}

message StreamAnalytics {
  string stream_id = 1;
  int64 start_time = 2;
  int64 end_time = 3;
  int32 unique_listeners = 4;
  int32 max_concurrent = 5;
  int64 total_listen_time = 6;
  float average_session_duration = 7;
  map<string, int32> geographic_distribution = 8;
  repeated ListenerActivity hourly_activity = 9;
}

message ListenerActivity {
  int64 timestamp = 1;
  int32 listener_count = 2;
  int32 new_listeners = 3;
  int32 listeners_left = 4;
}

message UserListeningHistory {
  int64 user_id = 1;
  repeated ListeningSession sessions = 2;
  int64 total_listen_time = 3;
  int32 streams_listened = 4;
}

message ListeningSession {
  string stream_id = 1;
  string stream_title = 2;
  string streamer_username = 3;
  int64 started_at = 4;
  int64 duration = 5;
  StreamQuality quality = 6;
}

message StreamMetadata {
  string current_track = 1;
  string artist = 2;
  string album = 3;
  string genre = 4;
  map<string, string> custom_fields = 5;
}

message StreamEvent {
  string stream_id = 1;
  StreamEventType type = 2;
  int64 timestamp = 3;
  string data = 4; // JSON data
}

// Énumérations
enum StreamCategory {
  MUSIC = 0;
  TALK = 1;
  PODCAST = 2;
  GAMING = 3;
  NEWS = 4;
  EDUCATION = 5;
  ENTERTAINMENT = 6;
  OTHER = 7;
}

enum StreamVisibility {
  PUBLIC_STREAM = 0;
  UNLISTED = 1;
  PRIVATE_STREAM = 2;
  PREMIUM_ONLY = 3;
}

enum StreamStatus {
  CREATED = 0;
  LIVE = 1;
  PAUSED = 2;
  ENDED = 3;
  ERROR = 4;
}

enum StreamQuality {
  AUTO = 0;
  LOW = 1;    // 64 kbps
  MEDIUM = 2; // 128 kbps
  HIGH = 3;   // 256 kbps
  ULTRA = 4;  // 320 kbps
}

enum AudioCodec {
  MP3 = 0;
  AAC = 1;
  OPUS = 2;
  FLAC = 3;
}

enum StreamSortBy {
  LISTENERS = 0;
  RECENT = 1;
  POPULAR = 2;
  TITLE = 3;
}

enum RecordingStatus {
  RECORDING = 0;
  PROCESSING = 1;
  COMPLETED = 2;
  FAILED = 3;
}

enum StreamEventType {
  LISTENER_JOINED = 0;
  LISTENER_LEFT = 1;
  QUALITY_CHANGED = 2;
  METADATA_UPDATED = 3;
  STREAM_PAUSED = 4;
  STREAM_RESUMED = 5;
  ERROR_OCCURRED = 6;
} 