syntax = "proto3";

package com.wixpress.roles.management.api;

import "google/api/annotations.proto";
import "google/protobuf/wrappers.proto";
import "wix/api/validations.proto";
import "wix/api/callback.proto";
import "com/wixpress/invites/api/invites.proto";
import "wix/api/permissions.proto";
import "wix/api/annotations.proto";
import "wix/api/entity.proto";
import "users.proto";
import "account.proto";
import "team.proto";
import "policy.proto";
import "roles.proto";
import "people.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/field_mask.proto";

service SiteRolesManagementService {
    option (wix.api.service_entity).message = "com.wixpress.roles.management.api.Contributor";

    rpc GetSiteContributors (GetSiteContributorsRequest) returns (GetSiteContributorsResponse) {
        option (wix.api.exposure) = INTERNAL;
        option (google.api.http) = {
            get: "/contributors"
        };
    };

    // returns a list of all the contributors + invites to be contributors of a given meta site ID taken from the
    // context.
    rpc GetSiteContributorsV2 (GetSiteContributorsV2Request) returns (GetSiteContributorsV2Response) {
        option (wix.api.maturity) = ALPHA;
        option (wix.api.exposure) = PUBLIC;
        option (google.api.http) = {
            get: "/v2/contributors"
        };
        option (wix.api.permission).name = "site-users.view-users";
    };

    rpc HandleSiteTransfer(HandleSiteTransferRequest) returns (HandleSiteTransferResponse) {
        option (google.api.http).patch = "/transfer";
        option (wix.api.exposure) = INTERNAL;
        option (wix.api.permission).name = "SITE_ROLES.HANDLE_SITE_TRANSFER";
    };

  //flynt-disable rest-path-kebab-case
    rpc GetCurrentUserRoles (GetCurrentUserRolesRequest) returns (GetCurrentUserRolesResponse) {
        option (wix.api.exposure) = INTERNAL;
        option (google.api.http) = {
            get: "/myRoles"
        };
    };

    // Get a list of roles (localized) for each user in the request on a specific site taken from aspects.
    //flynt-disable rest-path-kebab-case
    rpc BulkGetUserRolesOnSite (BulkGetUserRolesOnSiteRequest) returns (BulkGetUserRolesOnSiteResponse) {
        option (wix.api.permission).name = "SITE_ROLES.BULK_READ";
        option (wix.api.exposure) = INTERNAL;
        option (google.api.http) = {
            get: "/bulkUserRoles"
        };
    };

    // Validating the eligibility of email site invites in bulk.
    //flynt-disable rest-path-kebab-case
    rpc BulkValidateEmailInviteEligibility (BulkValidateEmailInviteEligibilityRequest) returns (BulkValidateEmailInviteEligibilityResponse) {
        option (wix.api.permission).name = "SITE_ROLES.BULK_READ";
        option (wix.api.exposure) = INTERNAL;
        option (google.api.http) = {
            get: "/bulkValidateEmailInviteEligibility"
        };
    };

    // Overrides all the roles of a contributor for the specified site.
    //flynt-disable http-mapping-breaking-change
    rpc ChangeRole(ChangeContributorRoleRequest) returns (ChangeContributorRoleResponse) {
        option (wix.api.maturity) = GA;
        option (wix.api.exposure) = PUBLIC;
        option (google.api.http).put = "/contributor/change/role";
        option (wix.api.permission).name = "SITE_ROLES.CHANGE_ROLE";
        option (wix.api.required) = "ChangeContributorRoleRequest.account_id";
        option (wix.api.required) = "ChangeContributorRoleRequest.new_roles";
    }

    rpc ChangeContributorLocation(ChangeContributorLocationRequest) returns (ChangeContributorLocationResponse) {
        option (wix.api.maturity) = BETA;
        option (wix.api.exposure) = PUBLIC;
        option (google.api.http).put = "/contributor/change/locations";
        option (wix.api.permission).name = "SITE_ROLES.CHANGE_LOCATION";
        option (wix.api.required) = "ChangeContributorLocationRequest.account_id";
        option (wix.api.required) = "ChangeContributorLocationRequest.new_locations";
    }

    // Retrieves a list of contributors for the specified site, given the provided filters.
    rpc QuerySiteContributors (QuerySiteContributorsRequest) returns (QuerySiteContributorsResponse) {
        option (wix.api.maturity) = GA;
        option (wix.api.exposure) = PUBLIC;
        option (google.api.http) = {
            get: "/v2/contributors/query"
        };
        option (wix.api.permission).name = "site-users.view-users";
    };

    // returns the quota information for contributors on the given site.
    rpc GetContributorsQuota(GetContributorsQuotaRequest) returns (GetContributorsQuotaResponse) {
        option (wix.api.maturity) = ALPHA;
        option (wix.api.exposure) = PUBLIC;
        option (google.api.http) = {
            get: "/v2/contributors/quota"
        };
        option (wix.api.permission).name = "site-users.view-users";
    }
}

message GetCurrentUserRolesRequest {
    // The locale of the request. Defaults to en-us
    google.protobuf.StringValue locale = 1;
}

message GetCurrentUserRolesResponse {
    repeated LocalizedRole roles = 1;
}

message BulkGetUserRolesOnSiteRequest {
    repeated UserSubject users = 1 [(wix.api.maxSize) = 5];
    // The locale of the request. Defaults to en-us
    google.protobuf.StringValue locale = 2;
}

message BulkGetUserRolesOnSiteResponse {
    repeated UserLocalizedRoles user_roles = 1;
}

message BulkValidateEmailInviteEligibilityRequest {
    // List of emails to be checked for invite eligibility.
    repeated string emails = 1 [(.wix.api.minSize) = 1, (wix.api.maxSize) = 10, (wix.api.format) = EMAIL, (.wix.api.pii) = true];
}

message BulkValidateEmailInviteEligibilityResponse {
    // List of email invite eligibility results.
    repeated EmailInviteEligibility emails_eligibility = 1;
}

message ChangeContributorRoleRequest {
    string account_id = 1 [(wix.api.format) = GUID]; // Contributor's account ID.
    repeated SiteRoleAssignment new_roles = 2; // New roles to assign to the contributor on the site.
}

message ChangeContributorRoleResponse {
    repeated SiteRoleAssignment new_assigned_roles = 1; // New roles assigned to the contributor on the site.
}

message ChangeContributorLocationRequest {
    string account_id = 1 [(wix.api.format) = GUID]; // Contributor's account ID.
    repeated string new_locations = 2 [(wix.api.format) = GUID, (wix.api.maxSize) = 20]; // New locations to assign to the contributor on the site.
}

message ChangeContributorLocationResponse {
    repeated SiteLocationAssignment new_assigned_locations = 1 [(wix.api.maxSize) = 20]; // New locations assigned to the contributor on the site.
}

message SiteRoleAssignment {
    string role_id = 1; // Role ID. Sometimes referred to as policy ID. See [Roles and Permissions](https://support.wix.com/en/article/roles-permissions-overview) for a list of available roles.
    string assignment_id = 2 [(wix.api.readOnly) = true]; // Assignment ID mapping the role to the contributor on the site.
}

message SiteLocationAssignment {
    //flynt-disable field-type-breaking-change,renamed-field-breaking-change
    repeated string location_ids = 1 [(wix.api.format) = GUID, (wix.api.maxSize) = 100];
    repeated string assignment_ids = 2 [(wix.api.readOnly) = true, (wix.api.maxLength) = 20, (wix.api.maxSize) = 999];
}

message UserSubject {
    string user_id = 1;
    string account_id = 2;
}

message UserLocalizedRoles {
    UserSubject user = 1;
    repeated LocalizedRole roles = 2;
}

message EmailInviteEligibility {
    // The email address being checked.
    string email = 1 [(.wix.api.format) = EMAIL, (.wix.api.pii) = true];
    // Whether the email is eligible for an invite.
    bool eligible = 2;
}

message LocalizedRole {
    string name = 1;
    google.protobuf.StringValue description = 2;
}

message HandleSiteTransferRequest {
    string original_owner_account_id = 1;
    string new_owner_account_id = 2;
    string meta_site_id = 3;
    bool keep_original_owner_as_contributor = 4;
}

message HandleSiteTransferResponse { }

message GetSiteContributorsRequest {
    // The locale of the request. Defaults to en-us
    google.protobuf.StringValue locale = 1;
}

message GetSiteContributorsResponse {
    repeated User users = 1;
    repeated Team teams = 2;
    repeated com.wixpress.invites.api.SiteInvite invites = 3;
    repeated Policy policies = 4;
    repeated string permissions = 5;
    string user_id = 6;
    string logged_in_account_id = 7;
    PendingOwner pending_owner = 8;
    ContributorLimit contributor_limit = 9;
    PredefinedRoles predefined_roles = 10;
}

message GetSiteContributorsV2Request {
    // The locale of the request. Defaults to en-us.
    google.protobuf.StringValue locale = 1;
    // The set of desired fields.
    google.protobuf.FieldMask fields = 2;
}

message GetSiteContributorsV2Response {
    // List of contributors of the given site.
    repeated Contributor contributors = 1;
    // List of invites to contribute to the given site.
    repeated com.wixpress.invites.api.SiteInvite invites = 2;
    // Quota information for contributors on the given site.
    ContributorsQuota contributors_quota = 3;
    // Pending owner information for the site.
    PendingOwner pending_owner = 4;
    // Enriched invites with localized policy information (flattened structure)
    repeated EnrichedSiteInvite enriched_invites = 5 [(wix.api.maxSize) = 20];
}

message QuerySiteContributorsFilter {
    // Role IDs (referred to here as policy IDs) to return. See [Roles and Permissions](https://support.wix.com/en/article/roles-permissions-overview) for available roles.
    repeated string policy_ids = 1 [(wix.api.maxSize) = 20];
    // Location IDs.
    repeated string location_ids = 2 [(wix.api.format) = GUID, (wix.api.maxSize) = 20];
}

message QuerySiteContributorsRequest {
    // 
    enum FieldSet {
        UNKNOWN = 0;
        META_DATA = 1; // Include only `account_id` and `account_owner_id` fields. 
    }
    QuerySiteContributorsFilter filter = 1;
    repeated FieldSet field_set = 2 [(wix.api.field_exposure) = INTERNAL];
}

message QuerySiteContributorsResponse {
    // List of site contributors.
    repeated ContributorV2 contributors = 1;
}

message PendingOwner {
    string email = 1 [(wix.api.pii) = true];
    google.protobuf.Timestamp expiration_date = 2;
    string accept_link = 3;
}

message ContributorLimit {
    int32 contributor_limit = 1;
}

message ContributorsQuota {
    // Enum to represent different types of contributors quota.
    enum Type {
        UNKNOWN = 0;
        LIMITED = 1;
        UNLIMITED = 2;
    }

    // Details for a limited contributors quota.
    message LimitedOptions {
        // Maximum number of contributors allowed.
        int32 limit = 1;
        // Number of accepted or pending invitations.
        int32 used = 2;
    }

    // Type of contributors quota
    Type type = 1;
    oneof options {
        option (.wix.api.aligned_with_enum).field = "type";
        // Limited contributors quota details.
        LimitedOptions limited_options = 2;
    }
}

message GetContributorsQuotaRequest {}

message GetContributorsQuotaResponse {
    // Quota information for contributors on the given site.
    ContributorsQuota contributors_quota = 1;
}

// Localized policy information for a specific policy
message LocalizedPolicyInfo {
    string policy_id = 1[(wix.api.maxLength) = 50]; // Policy ID (role ID)
    string title = 2 [(wix.api.maxLength) = 500]; // Localized policy title
    string description = 3 [(wix.api.maxLength) = 1000]; // Localized policy description
}

// Enriched site invite with flattened structure including all invite fields plus localized policy info
message EnrichedSiteInvite {
    // Core invite fields (flattened from SiteInvite)
    string id = 1 [(wix.api.format) = GUID];
    string email = 2 [(wix.api.format) = EMAIL, (wix.api.pii) = true];
    string accept_link = 3[(wix.api.maxLength) = 50];
    google.protobuf.Timestamp date_created = 4;
    repeated string policy_ids = 5 [(wix.api.maxSize) = 20,(wix.api.maxLength) = 20];
    // Additional invite fields that may exist
    string inviter_id = 6[(wix.api.maxLength) = 50];;
    string site_id = 7[(wix.api.maxLength) = 50];;
    // Additional SiteInvite fields
    string status = 8[(wix.api.maxLength) = 50];;
    google.protobuf.Timestamp expiration_date = 9;

    repeated string location_ids = 11 [(wix.api.format) = GUID, (wix.api.maxSize) = 20];
    // Enriched policy information with localized titles and descriptions
    repeated LocalizedPolicyInfo policies = 20 [(wix.api.maxSize) = 20];
}

