syntax = "proto3";

package devvit.dev_portal;

import "devvit/data/api/admin/rfr/research_organization.proto";
import "devvit/data/api/admin/rfr/researcher.proto";
// portal imports
import "devvit/dev_portal/app/app.proto";
import "devvit/dev_portal/app/categories/categories.proto";
import "devvit/dev_portal/app/info/app_info.proto";
import "devvit/dev_portal/app_publish_request/app_publish_request.proto";
import "devvit/dev_portal/app_publish_request/modmail/app_publish_request_modmail.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_settings/app_settings.proto";
import "devvit/dev_portal/app_version/app_version.proto";
import "devvit/dev_portal/app_version/info/app_version_info.proto";
import "devvit/dev_portal/data_api/admin/audit/audit.proto";
import "devvit/dev_portal/data_api/admin/auth/auth.proto";
import "devvit/dev_portal/data_api/admin/organization/organization.proto";
import "devvit/dev_portal/data_api/admin/subscription/subscription.proto";
import "devvit/dev_portal/data_api/admin/user/user.proto";
import "devvit/dev_portal/developer_account/developer_account.proto";
import "devvit/dev_portal/feedback/feedback.proto";
import "devvit/dev_portal/installation/installation.proto";
import "devvit/dev_portal/installation_settings/installation_settings.proto";
import "devvit/dev_portal/nutrition/nutrition.proto";
import "devvit/dev_portal/payments/payments_verification.proto";
import "devvit/dev_portal/payments/product.proto";
// utils
import "devvit/uuid.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/struct.proto";

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

service App {
  rpc Create(app.AppCreationRequest) returns (app.info.AppInfo);

  rpc Search(app.AppSearchRequest) returns (app.AppSearchResponse);

  rpc GetBySlug(app.GetAppBySlugRequest) returns (app.FullAppInfo);
  rpc GetByUUID(UUID) returns (app.FullAppInfo);

  rpc GetAllWithLocation(installation.GetAllWithInstallLocationRequest) returns (app.info.MultipleAppInfos);
  rpc GetAllWithInstaller(installation.GetAllWithInstallerRequest) returns (app.info.MultipleAppInfos);
  rpc GetAllWithOwner(app.GetAllWithOwnerRequest) returns (app.info.MultipleAppInfos);

  // Get the X most popular apps, as determined by number of installations.
  rpc GetPopularApps(app.GetPopularAppsRequest) returns (app.info.MultipleAppInfos);

  rpc CheckIfMediaExists(app.CheckIfMediaExistsRequest) returns (app.CheckIfMediaExistsResponse);
  rpc UploadNewMedia(app.UploadNewMediaRequest) returns (app.UploadNewMediaResponse);

  rpc Update(app.AppUpdateRequest) returns (app.FullAppInfo);

  rpc Disable(app.DisableAppRequest) returns (google.protobuf.Empty);
  rpc Enable(app.EnableAppRequest) returns (google.protobuf.Empty);

  rpc Exists(app.AppExistsRequest) returns (app.AppExistsResponse);

  rpc AppAccountExists(app.AppAccountExistsRequest) returns (app.AppAccountExistsResponse);
  rpc CreateAppAccount(app.CreateAppAccountRequest) returns (app.CreateAppAccountResponse);
  rpc RecoverAppAccount(app.RecoverAppAccountRequest) returns (app.info.AppInfo);
  // Retrieve the full category taxonomy as a nested tree structure.
  rpc GetAllCategories(google.protobuf.Empty) returns (app.categories.AppCategoryNodeListResponse);
}

service AppVersion {
  rpc Create(app_version.AppVersionCreationRequest) returns (app_version.info.AppVersionInfo);

  rpc Get(UUID) returns (app_version.FullAppVersionInfo);
  rpc GetBySlugAndVersionNumber(app_version.AppSlugAndVersion) returns (app_version.FullAppVersionInfo);

  rpc Update(app_version.AppVersionUpdateRequest) returns (app_version.FullAppVersionInfo);

  rpc GetValidInstallLocations(app_version.ValidInstallLocationsRequest) returns (app_version.ValidInstallLocationsResponse);
  rpc GetAppVersionBundle(UUID) returns (app_version.GetAppVersionBundleResponse);

  // Get app nutritional labels by app name (slug) and optional version (1.2.3,
  // 1.2.3.4, latest). Unlike SemVer, latest includes pre-release versions, not
  // just stable.
  rpc GetNutritionByNameVersion(nutrition.GetNutritionByNameVersionRequest) returns (nutrition.MultipleNutritionCategories);

  // Get app nutritional labels by app version id
  rpc GetNutritionByAppVersionId(UUID) returns (nutrition.MultipleNutritionCategories);

  // Get app products by app version id
  rpc GetProductsByAppVersionId(UUID) returns (payments.ProductList);
}

// Currently, there are no Actors or ActorTypes services. If use cases appear for either of these
// services, this is where they'd go.

service Installations {
  rpc Create(installation.InstallationCreationRequest) returns (installation.FullInstallationInfo);

  rpc GetByUUID(UUID) returns (installation.FullInstallationInfo);
  rpc GetByAppNameAndInstallLocation(installation.GetByAppNameAndInstallLocationRequest) returns (installation.FullInstallationInfo);

  rpc GetAllWithInstallLocation(installation.GetAllWithInstallLocationRequest) returns (installation.MultipleInstallationsResponse);
  rpc GetAllWithInstaller(installation.GetAllWithInstallerRequest) returns (installation.MultipleInstallationsResponse);
  rpc GetAllWithVersionUUID(installation.GetAllWithVersionUUIDRequest) returns (installation.MultipleInstallationsResponse);
  rpc GetAllWithApp(installation.GetAllWithAppRequest) returns (installation.GetAllWithAppResponse);
  rpc GetInstallationHistory(installation.GetInstallationHistoryRequest) returns (installation.GetInstallationHistoryResponse);

  rpc Upgrade(installation.InstallationUpgradeRequest) returns (installation.FullInstallationInfo);
  rpc UpgradeMany(installation.InstallationUpgradeManyRequest) returns (installation.InstallationUpgradeManyResponse);

  rpc Update(installation.InstallationUpdateRequest) returns (installation.FullInstallationInfo);

  rpc Remove(UUID) returns (google.protobuf.Empty);
}

service Feedback {
  rpc Create(feedback.CreateFeedbackRequest) returns (google.protobuf.Empty);
}

service DataApiAdmin {
  // Data Token
  rpc CreateDataToken(data_api.admin.auth.CreateDataTokenRequest) returns (data_api.admin.auth.CreateDataTokenResponse);
  rpc GetDataTokenById(data_api.admin.auth.GetDataTokenByIdRequest) returns (data_api.admin.auth.GetDataTokenByIdResponse);
  rpc GetDataTokensByOrganizationName(data_api.admin.auth.GetDataTokensByOrganizationNameRequest) returns (data_api.admin.auth.GetDataTokensByOrganizationNameResponse);
  rpc RevokeDataTokenById(data_api.admin.auth.RevokeDataTokenByIdRequest) returns (data_api.admin.auth.RevokeDataTokenByIdResponse);

  // Data Subscription
  rpc CreateDataSubscription(data_api.admin.subscription.CreateDataSubscriptionRequest) returns (data_api.admin.subscription.CreateDataSubscriptionResponse);
  rpc GetDataSubscriptionById(data_api.admin.subscription.GetDataSubscriptionByIdRequest) returns (data_api.admin.subscription.GetDataSubscriptionByIdResponse);
  rpc GetDataSubscriptionsByOrganizationName(data_api.admin.subscription.GetDataSubscriptionsByOrganizationNameRequest) returns (data_api.admin.subscription.GetDataSubscriptionsByOrganizationNameResponse);
  rpc UpdateDataSubscription(data_api.admin.subscription.UpdateDataSubscriptionRequest) returns (data_api.admin.subscription.UpdateDataSubscriptionResponse);
  rpc DeleteDataSubscription(data_api.admin.subscription.DeleteDataSubscriptionRequest) returns (data_api.admin.subscription.DeleteDataSubscriptionResponse);

  // Organizations
  rpc CreateOrganization(data_api.admin.organization.CreateOrganizationRequest) returns (data_api.admin.organization.CreateOrganizationResponse);
  rpc GetOrganizationByName(data_api.admin.organization.GetOrganizationByNameRequest) returns (data_api.admin.organization.GetOrganizationByNameResponse);
  rpc GetOrganizations(data_api.admin.organization.GetOrganizationsRequest) returns (data_api.admin.organization.GetOrganizationsResponse);
  rpc UpdateOrganization(data_api.admin.organization.UpdateOrganizationRequest) returns (data_api.admin.organization.UpdateOrganizationResponse);

  // Audit Log
  rpc GetAuditLogEvents(data_api.admin.audit.GetAuditLogEventsRequest) returns (data_api.admin.audit.GetAuditLogEventsResponse);

  rpc AddUsersToOrg(data_api.admin.user.AddUsersToOrgRequest) returns (data_api.admin.user.AddUsersToOrgResponse);
  rpc GetUsersByOrgId(data_api.admin.user.GetUsersByOrgIdRequest) returns (data_api.admin.user.GetUsersByOrgIdResponse);
  rpc GetUserById(data_api.admin.user.GetUserByIdRequest) returns (data_api.admin.user.GetUserByIdResponse);
  rpc DeleteUser(data_api.admin.user.DeleteUserRequest) returns (data_api.admin.user.DeleteUserResponse);

  // Reddit for Researchers Organizations
  rpc CreateResearchOrganization(devvit.data.api.admin.CreateResearchOrganizationRequest) returns (devvit.data.api.admin.CreateResearchOrganizationResponse);
  rpc GetResearchOrganizations(devvit.data.api.admin.GetResearchOrganizationsRequest) returns (devvit.data.api.admin.GetResearchOrganizationsResponse);
  rpc UpdateResearchOrganization(devvit.data.api.admin.UpdateResearchOrganizationByIdRequest) returns (devvit.data.api.admin.UpdateResearchOrganizationResponse);
  rpc GetResearchOrganization(devvit.data.api.admin.GetResearchOrganizationByIdRequest) returns (devvit.data.api.admin.GetResearchOrganizationByIdResponse);
  rpc DeleteResearchOrganization(devvit.data.api.admin.DeleteResearchOrganizationRequest) returns (devvit.data.api.admin.DeleteResearchOrganizationResponse);

  // Reddit for Researchers Users
  rpc CreateResearcher(devvit.data.api.admin.CreateResearcherRequest) returns (devvit.data.api.admin.CreateResearcherResponse);
  rpc GetResearchers(devvit.data.api.admin.GetResearchersRequest) returns (devvit.data.api.admin.GetResearchersResponse);
  rpc GetResearcher(devvit.data.api.admin.GetResearcherByIdRequest) returns (devvit.data.api.admin.GetResearcherByIdResponse);
  rpc GetResearchersByOrganizationId(devvit.data.api.admin.GetResearchersByOrganizationIdRequest) returns (devvit.data.api.admin.GetResearchersByOrganizationIdResponse);
  rpc DeleteResearcher(devvit.data.api.admin.DeleteResearcherRequest) returns (devvit.data.api.admin.DeleteResearcherResponse);
}

// A service to handle client-side events.
service Events {
  // Fire off a client-side event
  rpc SendEvent(google.protobuf.Value) returns (google.protobuf.Empty);
}

service DevPortalInstallationSettings {
  rpc GetForm(installation_settings.GetInstallationSettingsFormRequest) returns (installation_settings.GetInstallationSettingsFormResponse);
  rpc ValidateForm(installation_settings.ValidateInstallationSettingsFormRequest) returns (installation_settings.ValidateInstallationSettingsFormResponse);
  rpc GetSettings(installation_settings.GetInstallationSettingsRequest) returns (installation_settings.GetInstallationSettingsResponse);
  rpc UpdateSettings(installation_settings.UpdateInstallationSettingsRequest) returns (installation_settings.UpdateInstallationSettingsResponse);
}

service DevPortalAppSettings {
  rpc GetForm(app_settings.GetAppSettingsFormRequest) returns (app_settings.GetAppSettingsFormResponse);
  rpc ValidateForm(app_settings.ValidateAppSettingsFormRequest) returns (app_settings.ValidateAppSettingsFormResponse);
  rpc GetSettings(app_settings.GetAppSettingsRequest) returns (app_settings.GetAppSettingsResponse);
  rpc UpdateSettings(app_settings.UpdateAppSettingsRequest) returns (app_settings.UpdateAppSettingsResponse);
}

// Service to support developer settings page. See here: https://docs.google.com/document/d/1HuAfNB_26jnNu7gGDHk-vafzgpnoNaFqHoumE2C40cA/edit?tab=t.0#bookmark=id.9kf1k0pojgnq
// for more context.
service DevPortalDeveloperSettings {
  // Returns the payments verification status for a given user. This determines whether the user can get paid out and
  // whether they can publish apps that accept payments.
  rpc GetPaymentsVerificationStatus(payments.GetPaymentsVerificationStatusRequest) returns (payments.GetPaymentsVerificationStatusResponse);
}

service DevPortalAppPublishRequest {
  rpc Submit(app_publish_request.AppPRCreateRequest) returns (UUID);
  rpc Update(app_publish_request.AppPRUpdateRequest) returns (google.protobuf.Empty);
  rpc Get(app_publish_request.AppPRGetRequest) returns (app_publish_request.FullPublishRequestInfo);
  rpc FindMany(app_publish_request.AppPRFindManyRequest) returns (app_publish_request.MultiplePublishRequestInfos);

  rpc SetReviewDecision(app_publish_request.review.AppPRSetReviewDecisionRequest) returns (UUID);
  rpc RemoveReview(UUID) returns (google.protobuf.Empty);

  rpc AddNote(app_publish_request.note.AppPRAddNoteRequest) returns (UUID);
  rpc UpdateNote(app_publish_request.note.AppPRUpdateNoteRequest) returns (google.protobuf.Empty);
  rpc RemoveNote(UUID) returns (google.protobuf.Empty);

  rpc ListModmailConversations(app_publish_request.modmail.AppPRListModmailConversationsRequest) returns (app_publish_request.modmail.AppPRListModmailConversationsResponse);
  // Modmail-specific review flow. This updates the review decision and sends
  // the modmail payload in one RPC. Use SetReviewDecision for non-modmail
  // workflows.
  rpc SetReviewDecisionWithModmail(app_publish_request.modmail.AppPRSetReviewDecisionWithModmailRequest) returns (app_publish_request.modmail.AppPRSetReviewDecisionWithModmailResponse);
}

// Developer Account service, for managing when users register their Reddit account for a Developer Account
// A Developer account is specific to the Developer Platform, and is necessary to develop apps
service DeveloperAccount {
  rpc RegisterUser(developer_account.DeveloperAccountRegisterUserRequest) returns (developer_account.DeveloperAccountInfo);
  rpc GetUserAccountInfoIfExists(google.protobuf.Empty) returns (developer_account.GetUserAccountInfoResponse);
}
