syntax = "proto3";

package devvit.dev_portal.app_publish_request;

import "devvit/dev_portal/app/info/app_info.proto";
import "devvit/dev_portal/app_publish_request/note/app_publish_request_note.proto";
import "devvit/dev_portal/app_publish_request/review/app_publish_request_review.proto";
import "devvit/dev_portal/app_version/info/app_version_info.proto";
import "devvit/dev_portal/reddit/redditor.proto";
import "google/protobuf/timestamp.proto";

option go_package = "github.snooguts.net/reddit/reddit-devplatform-monorepo/go-common/generated/protos/types/devvit/devportal/apppublishrequest";

enum AppPublishRequestStatus {
  APPROVED = 0;
  DENIED = 1;
  OBSOLETE = 2;
  PENDING = 3;
  WITHDRAWN = 4;
}

enum AppPublishRequestVisibility {
  PUBLIC = 0;
  UNLISTED = 1;
}

// AppPublishRequestPendingState describes the queue context for a pending
// app publish request. This metadata is secondary to the primary request
// status and is used to clarify why a request is still in review.
enum AppPublishRequestPendingState {
  AWAITING_REVIEW = 0;
  AWAITING_PANEL_REVIEW = 1;
  IN_REVIEW = 2;
  ON_HOLD = 3;
}

enum AutomatedAppReviewDecision {
  AUTOMATED_APP_REVIEW_DECISION_UNSPECIFIED = 0;
  AUTOMATED_APP_REVIEW_DECISION_APPROVED = 1;
  AUTOMATED_APP_REVIEW_DECISION_REJECTED = 2;
  AUTOMATED_APP_REVIEW_DECISION_NEEDS_REVIEW = 3;
}

enum AutomatedAppReviewStatus {
  AUTOMATED_APP_REVIEW_STATUS_UNSPECIFIED = 0;
  AUTOMATED_APP_REVIEW_STATUS_PENDING = 1;
  AUTOMATED_APP_REVIEW_STATUS_COMPLETED = 2;
  AUTOMATED_APP_REVIEW_STATUS_ERROR = 3;
  AUTOMATED_APP_REVIEW_STATUS_RATE_LIMITED = 4;
}

message AutomatedAppReview {
  string id = 1;
  google.protobuf.Timestamp created_at = 2;
  google.protobuf.Timestamp updated_at = 3;
  string execution_id = 4;
  string model = 5;
  string response = 6;
  AutomatedAppReviewDecision decision = 7;
  AutomatedAppReviewStatus status = 8;
}

message FullPublishRequestInfo {
  string id = 1;
  google.protobuf.Timestamp created_at = 2;
  devvit.dev_portal.reddit.Redditor created_by = 3;

  AppPublishRequestStatus status = 4;
  AppPublishRequestVisibility visibility = 10;

  devvit.dev_portal.app_version.info.AppVersionInfo app_version_info = 5;
  devvit.dev_portal.app.info.AppInfo app_info = 6;

  repeated devvit.dev_portal.app_publish_request.review.AppPublishRequestReview reviews = 7;
  repeated devvit.dev_portal.app_publish_request.note.AppPublishRequestNote notes = 8;

  // the number of subreddit the target app is installed to
  optional int32 app_installation_count = 9;

  repeated AutomatedAppReview automated_reviews = 11;

  // pending_state captures the queue context for this publish request.
  // Only set when status is PENDING, OBSOLETE, or WITHDRAWN; null otherwise.
  optional AppPublishRequestPendingState pending_state = 12;

  // Next number is 13
}

message MultiplePublishRequestInfos {
  message PageInfo {
    // current page number (min 1)
    int32 page = 1;
    // items per page
    int32 page_size = 2;
    // total number of items for the current search criteria
    int32 total = 3;
  }

  repeated FullPublishRequestInfo requests = 1;
  PageInfo pagination = 2;
}

message AppPRCreateRequest {
  oneof identifier {
    string app_version_id = 1;
    // e.g. "comment-nuke@4.2.0"
    string app_slug_and_version_number = 2;
  }

  AppPublishRequestVisibility visibility = 3;
}

message AppPRUpdateRequest {
  oneof identifier {
    string app_version_id = 1;
    string publish_request_id = 2;
    // e.g. "comment-nuke@4.2.0"
    string app_slug_and_version_number = 3;
  }
  AppPublishRequestStatus status = 4;
  optional AppPublishRequestPendingState pending_state = 5;
}

message AppPRGetRequest {
  oneof identifier {
    string app_version_id = 1;
    string publish_request_id = 2;
    // e.g. "comment-nuke@4.2.0"
    string app_slug_and_version_number = 3;
  }
}

message AppPRFindManyRequest {
  message PaginationInfo {
    // page number (min 1)
    int32 page = 1;
    // items per page
    int32 page_size = 2;
  }

  message SortInfo {
    // field name to sort by
    string field = 1;
    // direction (true = ascending, false = descending)
    bool asc = 2;
  }

  oneof filter_apps_by {
    // unique App Id
    string app_id = 1;
    // full match by App name (not a slug)
    string app_name = 2;
    // full match by App slug
    string app_slug = 3;
    // partial match by App slug or name
    string search_term = 4;
  }

  PaginationInfo pagination = 5;
  // how the results should be sorted
  SortInfo sort = 6;
  // filter PRs by status (an "OR" rule is applied if more than one status is specified)
  repeated AppPublishRequestStatus statuses = 7;
  // filter pending PRs by queue state (an "OR" rule is applied if more than one state is specified)
  repeated AppPublishRequestPendingState pending_states = 8;
}
