syntax = "proto3";
package provenance.registry.v1;

option go_package          = "github.com/provenance-io/provenance/x/registry/types";
option java_package        = "io.provenance.registry.v1";
option java_multiple_files = true;

import "gogoproto/gogo.proto";
import "cosmos_proto/cosmos.proto";
import "cosmos/msg/v1/msg.proto";
import "provenance/registry/v1/registry.proto";

// Msg defines the registry Msg service.
// This service provides transaction functionality for managing registry entries and roles.
service Msg {
  option (cosmos.msg.v1.service) = true;

  // RegisterNFT registers a new NFT in the registry.
  // This creates a new registry entry with the specified roles and addresses.
  rpc RegisterNFT(MsgRegisterNFT) returns (MsgRegisterNFTResponse);

  // GrantRole grants a role to one or more addresses.
  // This adds the specified addresses to the role for the given registry key.
  rpc GrantRole(MsgGrantRole) returns (MsgGrantRoleResponse);

  // RevokeRole revokes a role from one or more addresses.
  // This removes the specified addresses from the role for the given registry key.
  rpc RevokeRole(MsgRevokeRole) returns (MsgRevokeRoleResponse);

  // UnregisterNFT unregisters an NFT from the registry.
  // This removes the entire registry entry for the specified key.
  rpc UnregisterNFT(MsgUnregisterNFT) returns (MsgUnregisterNFTResponse);

  // RegistryBulkUpdate registers, or updates, multiple NFTs in the registry.
  // This creates multiple registry entries, or updates if one exists.
  // Each registry in this will cost one MsgRegisterNFT.
  rpc RegistryBulkUpdate(MsgRegistryBulkUpdate) returns (MsgRegistryBulkUpdateResponse);
}

// MsgRegisterNFT represents a message to register a new NFT in the registry.
// This message creates a new registry entry with the specified roles and addresses.
message MsgRegisterNFT {
  option (cosmos.msg.v1.signer) = "signer";

  // signer is the address that is authorized to register NFTs.
  // This address must have the appropriate permissions to create registry entries.
  string signer = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];

  // key is the registry key to register.
  // This contains the NFT ID and asset class ID that uniquely identify the registry entry.
  RegistryKey key = 2;

  // roles is a list of roles and addresses that can perform that role.
  // Each role entry defines a role type and the addresses authorized for that role.
  repeated RolesEntry roles = 3 [(gogoproto.nullable) = false];
}

// MsgRegisterNFTResponse defines the response for RegisterNFT.
// This is an empty response indicating successful registration.
message MsgRegisterNFTResponse {}

// MsgGrantRole represents a message to grant a role to one or more addresses.
// This message adds the specified addresses to an existing role for the given registry key.
message MsgGrantRole {
  option (cosmos.msg.v1.signer) = "signer";

  // signer is the address that is authorized to grant the role.
  // This address must have the appropriate permissions to modify role assignments.
  string signer = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];

  // key is the registry key to grant the role to.
  // This identifies the specific registry entry to modify.
  RegistryKey key = 2;

  // role is the role to grant.
  // This specifies which role type is being assigned to the addresses.
  RegistryRole role = 3;

  // addresses is the list of addresses to grant the role to.
  // These addresses will be added to the specified role for the registry key.
  repeated string addresses = 4 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// MsgGrantRoleResponse defines the response for GrantRole.
// This is an empty response indicating successful role grant.
message MsgGrantRoleResponse {}

// MsgRevokeRole represents a message to revoke a role from one or more addresses.
// This message removes the specified addresses from an existing role for the given registry key.
message MsgRevokeRole {
  option (cosmos.msg.v1.signer) = "signer";

  // signer is the address that is authorized to revoke the role.
  // This address must have the appropriate permissions to modify role assignments.
  string signer = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];

  // key is the registry key to revoke the role from.
  // This identifies the specific registry entry to modify.
  RegistryKey key = 2;

  // role is the role to revoke.
  // This specifies which role type is being removed from the addresses.
  RegistryRole role = 3;

  // addresses is the list of addresses to revoke the role from.
  // These addresses will be removed from the specified role for the registry key.
  repeated string addresses = 4 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// MsgRevokeRoleResponse defines the response for RevokeRole.
// This is an empty response indicating successful role revocation.
message MsgRevokeRoleResponse {}

// MsgUnregisterNFT represents a message to unregister an NFT from the registry.
// This message removes the entire registry entry for the specified key.
message MsgUnregisterNFT {
  option (cosmos.msg.v1.signer) = "signer";

  // signer is the address that is authorized to unregister NFTs.
  // This address must have the appropriate permissions to remove registry entries.
  string signer = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];

  // key is the registry key to remove.
  // This identifies the specific registry entry to delete.
  RegistryKey key = 2;
}

// MsgUnregisterNFTResponse defines the response for UnregisterNFT.
// This is an empty response indicating successful unregistration.
message MsgUnregisterNFTResponse {}

// MsgRegistryBulkUpdate represents a bulk update operation for multiple registry entries.
// This allows for efficient batch processing of registry modifications.
message MsgRegistryBulkUpdate {
  option (cosmos.msg.v1.signer) = "signer";

  // signer is the address that is authorized to register NFTs.
  // This address must have the appropriate permissions to create registry entries.
  string signer = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];

  // entries is the list of bulk update entries to be processed.
  // Each entry contains the registry entry to be updated.
  repeated RegistryEntry entries = 2 [(gogoproto.nullable) = false];
}

// MsgRegistryBulkUpdateResponse defines the response for RegistryBulkUpdate.
// This is an empty response indicating successful bulk update.
message MsgRegistryBulkUpdateResponse {}