syntax = "proto3";

package devvit.plugin.externalendpoints.v1alpha;

import "google/protobuf/timestamp.proto";

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

service ExternalEndpointsInternal {
  rpc CreateManagedToken(CreateManagedTokenRequest) returns (CreateManagedTokenResponse);
  // Validate a callback or managed token. Returns an empty response
  // (`token_id == ""`) if the token is invalid. Updates last used timestamp.
  rpc ValidateToken(ValidateTokenRequest) returns (ValidateTokenResponse);
  // Deletes the token. Called by gateway after a successful app invocation. If
  // the app errored, gateway does not consume; the row stays alive and the
  // callback URL can be retried until its TTL expires. Intentional app failures
  // and concurrent requests are not prevented.
  rpc ConsumeCallbackToken(ConsumeCallbackTokenRequest) returns (ConsumeCallbackTokenResponse);
  // List all tokens for an app.
  rpc ListTokens(ListTokensRequest) returns (ListTokensResponse);
  rpc RevokeToken(RevokeTokenRequest) returns (RevokeTokenResponse);
}

// Snapshot of the request context at the time a callback URL was generated.
// "Generator" here refers to whoever called `getCallbackUrl()`. This data is
// used to revive the generator's context when the callback is invoked some
// minutes later in a new request context.
message CallbackContext {
  // Generator's Reddit user ID. Eg, `t2_abc123`. May be empty.
  string user_t2 = 1;
  // Generator's installation identifier (UUID). Eg,
  // `f47ac10b-58cc-4372-a567-0e02b2c3d479`.
  string installation_id = 2;
  // Generator's subreddit ID. Eg, `t5_2qh1i`. May be empty.
  string subreddit_t5 = 3;
  // Generator's post ID. Eg, `t3_1a2b3c`. May be empty.
  string post_t3 = 4;
  // Generator's comment ID. Eg, `t1_abc123`. May be empty.
  string comment_t1 = 5;
  // Generator's logged-out user identifier (HMAC of `installationId:LOID`).
  string user_loid = 7;
  // Generator's user locale at callback creation time. Eg, `en-US`.
  string accept_language = 8;
  // Generator's user timezone at callback creation time. Eg,
  // `America/Los_Angeles`.
  string accept_timezone = 9;
}

message ConsumeCallbackTokenRequest {
  // The UUID of the callback token to delete.
  string token_id = 1;
}

message ConsumeCallbackTokenResponse {}

message CreateManagedTokenRequest {
  // Unique user provided name to identify the token. Eg, `game-api-token`.
  string token_name = 1;
}

message CreateManagedTokenResponse {
  Token token = 1;
}

message ListTokensRequest {
  // The app slug to list tokens for. Eg, `wsbapp`.
  string app_slug = 1;
}

message ListTokensResponse {
  // All tokens associated with the app.
  repeated Token tokens = 1;
}

message RevokeTokenRequest {
  // The UUID of the token to revoke.
  string token_id = 1;
}

message RevokeTokenResponse {}

// No field is considered sensitive except `Token.token`.
message Token {
  // Token UUID.
  string id = 1;
  // Unique user provided token identifier conforming to `[a-zA-Z0-9_-]+`. Eg,
  // `game-api-token`. Always present for managed tokens, absent for single-use
  // callback tokens.
  string name = 2;
  // The token value (only returned on creation). Eg, `devvit_at_abc123`.
  optional string token = 3;
  // When the token was created.
  google.protobuf.Timestamp created_at = 4;
  // Reddit user ID (`t2_abc123`) of the token creator.
  string created_by_t2 = 5;
}

message ValidateTokenRequest {
  // The token to validate. Eg, `devvit_at_abc123`.
  string token = 1;
}

message ValidateTokenResponse {
  // The app slug that owns this token (populated when valid). Eg, `wsbapp`.
  string app_slug = 1;

  // Callback context (populated only for valid callback tokens).
  // Presence indicates a callback token; absence indicates a managed token.
  CallbackContext callback_context = 2;

  // Token UUID. Non-empty means the token is valid; empty means invalid.
  string token_id = 3;
}
