syntax = "proto3";

package devvit.plugin.telemetry;

option go_package = "github.snooguts.net/reddit/reddit-devplatform-monorepo/go-common/generated/devvit/plugin/telemetry";
option java_package = "com.reddit.devvit.plugin.telemetry";

// TelemetryPlugin allows apps to emit journey-based telemetry events for analytics and ranking.
service TelemetryPlugin {
  // Starts a new telemetry journey.
  rpc StartJourney(StartJourneyRequest) returns (StartJourneyResponse);

  // Records progress within a journey.
  rpc JourneyProgress(JourneyProgressRequest) returns (JourneyProgressResponse);

  // Records an interaction within a journey.
  rpc JourneyInteraction(JourneyInteractionRequest) returns (JourneyInteractionResponse);

  // Ends a telemetry journey.
  rpc EndJourney(EndJourneyRequest) returns (EndJourneyResponse);

  // Signals that the app is ready and visible to the user.
  rpc AppReady(AppReadyRequest) returns (AppReadyResponse);
}

// Request to start a new telemetry journey.
message StartJourneyRequest {
  // Request is currently empty as journey ID is generated by the server.
}

// Response for starting a journey.
message StartJourneyResponse {
  // Unique identifier for the journey.
  // Example: "journey_1234567890"
  string journey_id = 1;
  JourneyReceipt receipt = 2;
}

// Structured receipt for a telemetry event attempt.
message JourneyReceipt {
  // Machine-readable status for tooling and tests.
  // Example: JOURNEY_RECEIPT_VALID
  JourneyReceiptStatus status = 1;
  // Human-readable status for developers.
  // Example: "Event is valid, but your app is not allowlisted for Journey telemetry yet, so it was not ingested."
  string message = 2;
}

// Machine-readable status for a telemetry event attempt.
enum JourneyReceiptStatus {
  // Status was not provided.
  JOURNEY_RECEIPT_UNSPECIFIED = 0;
  // Event was valid and sent to the telemetry pipeline.
  JOURNEY_RECEIPT_VALID = 1;
  // Event was valid, but not sent because the app is not allowlisted.
  JOURNEY_RECEIPT_DENIED_NOT_ALLOWLISTED = 2;
  // Event was valid, but not sent because the app exceeded rate limits.
  JOURNEY_RECEIPT_DENIED_RATE_LIMITED = 3;
  // Event was valid, but not sent because it was a duplicate.
  JOURNEY_RECEIPT_DENIED_DUPLICATE = 4;
  // Event was invalid and not sent to the telemetry pipeline.
  JOURNEY_RECEIPT_INVALID = 5;
}

// Request to record progress within a journey.
message JourneyProgressRequest {
  // Unique identifier for the journey.
  // Example: "journey_1234567890"
  string journey_id = 1;
  // Normalized progress value between 0.0 and 1.0.
  // Example: 0.5
  float progress = 2;
  // The action that occurred during the progress update.
  // Example: "level_complete"
  optional string action = 3;
  // Additional details about the action.
  // Example: "level_3"
  optional string action_details = 4;
}

// Response for recording journey progress.
message JourneyProgressResponse {
  JourneyReceipt receipt = 1;
}

// Request to record an interaction within a journey.
message JourneyInteractionRequest {
  // Unique identifier for the journey.
  // Example: "journey_1234567890"
  string journey_id = 1;
  // The action that occurred during the interaction.
  // Example: "word_complete"
  string action = 2;
  // Additional details about the action.
  // Example: "apple"
  string action_details = 3;
}

// Response for recording a journey interaction.
message JourneyInteractionResponse {
  JourneyReceipt receipt = 1;
}

// Game-specific result data for journey completion.
message GameResult {
  // Indicates if the user won the game.
  // Example: true
  bool win = 1;
  // The final score achieved in the game.
  // Example: 1000
  int64 score = 2;
}

// Request to end a telemetry journey.
message EndJourneyRequest {
  // Unique identifier for the journey.
  // Example: "journey_1234567890"
  string journey_id = 1;
  // Indicates if the journey objective was completed.
  // Example: true
  bool complete = 2;
  // Game-specific result data. Only applicable for game journeys.
  optional GameResult game = 3;
}

// Response for ending a journey.
message EndJourneyResponse {
  JourneyReceipt receipt = 1;
}

// Request to signal that the app is ready.
message AppReadyRequest {
  // Milliseconds elapsed from runtime initialization to app ready, measured by the platform runtime.
  // Example: 350
  int64 startup_time_ms = 1;
}

// Response for the app ready signal.
message AppReadyResponse {
  JourneyReceipt receipt = 1;
}
