// Copyright 2020-2025 Buf Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package buf.alpha.registry.v1alpha1;

import "buf/alpha/registry/v1alpha1/organization.proto";
import "buf/alpha/registry/v1alpha1/repository.proto";
import "buf/alpha/registry/v1alpha1/user.proto";
import "buf/alpha/registry/v1alpha1/verification_status.proto";
import "google/protobuf/timestamp.proto";

// BreakingChangeCategory is the allowed list of categories for breaking rule settings.
enum BreakingChangeCategory {
  BREAKING_CHANGE_CATEGORY_UNSPECIFIED = 0;
  BREAKING_CHANGE_CATEGORY_FILE = 1;
  BREAKING_CHANGE_CATEGORY_WIRE_JSON = 2;
}

message BreakingChangePolicy {
  optional bool enabled = 1;
  optional bool ignore_unstable_packages = 2;
  BreakingChangeCategory category = 3;
}

// UniquenessPolicy is the policy for uniqueness on the server.
message UniquenessPolicy {
  // Whether uniqueness policy is enforced.
  bool enabled = 1;
}

// Collision is a collision that has occurred.
message Collision {
  // The reference that has collisions.
  string reference = 1;
  // The type of collision.
  CollisionType type = 2;
  // The sources of the collision that the user is authorized to see.
  repeated CollisionSource sources = 3;
  // Whether there are other collision sources that the user is not authorized to see.
  // The user should contact a server admin for more information about these collisions.
  bool has_other_collision_sources = 4;
}

// CollisionSource is the source of a collision
message CollisionSource {
  // The name of the owner of the source.
  string owner_name = 1;
  // The name of the repository of the source.
  string repository_name = 2;
  // The path of the file that is the source of the collision.
  string path = 3;
}

// MonthlyUsage contains the total amount of message, enum and services types
// for every organizations repositories within a single tenant BSR instance
// for a given month and year.
message MonthlyUsage {
  // The month, between 1 and 12.
  uint32 month = 1;
  // The year, between 2020 and the current year.
  uint32 year = 2;
  // The total amount of message types for the month and year.
  uint32 total_message_types = 3;
  // The total amount of enum types for the month and year.
  uint32 total_enum_types = 4;
  // The total amount of method types for the month and year.
  uint32 total_method_types = 5;
}

// CollisionType is the type of collisions that can occur.
enum CollisionType {
  // Unspecified collision type.
  COLLISION_TYPE_UNSPECIFIED = 0;
  // A fully qualified proto name
  COLLISION_TYPE_FULLY_QUALIFIED_NAME = 1;
  // A proto file path
  COLLISION_TYPE_PATH = 2;
}

// AdminService is the Admin service.
service AdminService {
  // ForceDeleteUser forces to delete a user. Resources and organizations that are
  // solely owned by the user will also be deleted.
  rpc ForceDeleteUser(ForceDeleteUserRequest) returns (ForceDeleteUserResponse) {
    option idempotency_level = IDEMPOTENT;
  }
  // Update a user's verification status.
  rpc UpdateUserVerificationStatus(UpdateUserVerificationStatusRequest) returns (UpdateUserVerificationStatusResponse);
  // Update a organization's verification.
  rpc UpdateOrganizationVerificationStatus(UpdateOrganizationVerificationStatusRequest) returns (UpdateOrganizationVerificationStatusResponse);
  // Create a new machine user on the server.
  rpc CreateMachineUser(CreateMachineUserRequest) returns (CreateMachineUserResponse) {
    option idempotency_level = IDEMPOTENT;
  }
  // Get breaking change policy for the server.
  rpc GetBreakingChangePolicy(GetBreakingChangePolicyRequest) returns (GetBreakingChangePolicyResponse) {
    option idempotency_level = NO_SIDE_EFFECTS;
  }
  // Update breaking change policy for the server.
  rpc UpdateBreakingChangePolicy(UpdateBreakingChangePolicyRequest) returns (UpdateBreakingChangePolicyResponse);
  // Get uniqueness policy for the server.
  rpc GetUniquenessPolicy(GetUniquenessPolicyRequest) returns (GetUniquenessPolicyResponse) {
    option idempotency_level = NO_SIDE_EFFECTS;
  }
  // Update uniqueness policy enforcement for the server.
  rpc UpdateUniquenessPolicy(UpdateUniquenessPolicyRequest) returns (UpdateUniquenessPolicyResponse);
  // Get state of uniqueness collisions for the server
  rpc ListServerUniquenessCollisions(ListServerUniquenessCollisionsRequest) returns (ListServerUniquenessCollisionsResponse) {
    option idempotency_level = NO_SIDE_EFFECTS;
  }
  // Run a back-fill task to fill unique identifiers on the server.
  // This is a potentially long-running operation, and should only be triggered by the administrator of the server,
  // if they intend to enable uniqueness policy enforcement.
  // Successful completion of this operation is a pre-requisite for enabling uniqueness policy enforcement.
  rpc RunServerUniquenessBackfillTask(RunServerUniquenessBackfillTaskRequest) returns (RunServerUniquenessBackfillTaskResponse) {
    option idempotency_level = IDEMPOTENT;
  }
  // GetClusterUsage returns the summation of total message, enum and service types usage
  // for every repository in each organization within a single tenant BSR instance.
  rpc GetClusterUsage(GetClusterUsageRequest) returns (GetClusterUsageResponse);
}

message ForceDeleteUserRequest {
  string user_id = 1;
}

message ForceDeleteUserResponse {
  reserved 4, 5;
  reserved "plugins", "templates";

  // The deleted user.
  User user = 1;
  // The deleted organizations.
  repeated Organization organizations = 2;
  // The deleted repositories.
  repeated Repository repositories = 3;
}

message UpdateUserVerificationStatusRequest {
  string user_id = 1;
  VerificationStatus verification_status = 2;
}

message UpdateUserVerificationStatusResponse {}

message UpdateOrganizationVerificationStatusRequest {
  string organization_id = 1;
  VerificationStatus verification_status = 2;
}

message UpdateOrganizationVerificationStatusResponse {}

message CreateMachineUserRequest {
  string username = 1;
}

message CreateMachineUserResponse {
  User user = 1;
}

message GetBreakingChangePolicyRequest {}

message GetBreakingChangePolicyResponse {
  BreakingChangePolicy policy = 1;
}

message UpdateBreakingChangePolicyRequest {
  BreakingChangePolicy policy = 1;
}

message UpdateBreakingChangePolicyResponse {}

message GetUniquenessPolicyRequest {}

message GetUniquenessPolicyResponse {
  // The current uniqueness policy settings.
  UniquenessPolicy policy = 1;
  // Reports the status of the backfill task, which can be executed by the server admin with the
  // RunServerUniquenessBackfillTask RPC.
  bool backfill_task_complete = 2;
}

message UpdateUniquenessPolicyRequest {
  UniquenessPolicy policy = 1;
}

message UpdateUniquenessPolicyResponse {}

message ListServerUniquenessCollisionsRequest {
  // Token of the page to retrieve. If not specified, the first page of
  // results will be returned. Use the value obtained from `next_page_token`
  // in the previous response in order to request the next page of results.
  string page_token = 1;
  // Number of elements to retrieve in a single page.
  // When too large a page is requested, the server may decide to further
  // limit the number of returned resources.
  uint32 page_size = 2;
  // The desired collision type to filter by.
  // This must be specified. Only collisions of the specified type will be returned,
  // continue to page through results until no more collisions of the specified
  // type are returned.
  CollisionType collision_type = 3;
}

message ListServerUniquenessCollisionsResponse {
  // The collisions.
  repeated Collision collisions = 1;
  // Pagination token used to retrieve the next page of results.
  // Pass the content of this string as the `page_token` attribute of
  // the next request. `next_page_token` is not returned for the last
  // page.
  string next_page_token = 2;
}

message RunServerUniquenessBackfillTaskRequest {}

message RunServerUniquenessBackfillTaskResponse {}

message GetClusterUsageRequest {
  // The timestamp of the beginning time of a date range.
  google.protobuf.Timestamp start_time = 1;
  // The timestamp of the ending time of a date range.
  google.protobuf.Timestamp end_time = 2;
}

message GetClusterUsageResponse {
  repeated MonthlyUsage usage = 1;
}
