// PolicyService: CRUD management of policy rules.
syntax = "proto3";

package mcias.v1;

option go_package = "git.wntrmute.dev/mc/mcias/gen/mcias/v1;mciasv1";

// PolicyRule is the wire representation of a policy rule record.
message PolicyRule {
  int64  id          = 1;
  string description = 2;
  int32  priority    = 3;
  bool   enabled     = 4;
  string rule_json   = 5;  // JSON-encoded RuleBody
  string created_at  = 6;  // RFC3339
  string updated_at  = 7;  // RFC3339
  string not_before  = 8;  // RFC3339; empty if unset
  string expires_at  = 9;  // RFC3339; empty if unset
}

// --- List ---

message ListPolicyRulesRequest {}

message ListPolicyRulesResponse {
  repeated PolicyRule rules = 1;
}

// --- Create ---

message CreatePolicyRuleRequest {
  string description = 1;  // required
  string rule_json   = 2;  // required; JSON-encoded RuleBody
  int32  priority    = 3;  // default 100 when zero
  string not_before  = 4;  // RFC3339; optional
  string expires_at  = 5;  // RFC3339; optional
}

message CreatePolicyRuleResponse {
  PolicyRule rule = 1;
}

// --- Get ---

message GetPolicyRuleRequest {
  int64 id = 1;
}

message GetPolicyRuleResponse {
  PolicyRule rule = 1;
}

// --- Update ---

// UpdatePolicyRuleRequest carries partial updates.
// Fields left at their zero value are not changed on the server, except:
//   - clear_not_before=true removes the not_before constraint
//   - clear_expires_at=true removes the expires_at constraint
// has_priority / has_enabled use proto3 optional (field presence) so the
// server can distinguish "not supplied" from "set to zero/false".
message UpdatePolicyRuleRequest {
  int64           id              = 1;
  optional int32  priority        = 2;  // omit to leave unchanged
  optional bool   enabled         = 3;  // omit to leave unchanged
  string          not_before      = 4;  // RFC3339; ignored when clear_not_before=true
  string          expires_at      = 5;  // RFC3339; ignored when clear_expires_at=true
  bool            clear_not_before = 6;
  bool            clear_expires_at = 7;
}

message UpdatePolicyRuleResponse {
  PolicyRule rule = 1;
}

// --- Delete ---

message DeletePolicyRuleRequest {
  int64 id = 1;
}

message DeletePolicyRuleResponse {}

// PolicyService manages policy rules (admin only).
service PolicyService {
  // ListPolicyRules returns all policy rules.
  // Requires: admin JWT.
  rpc ListPolicyRules(ListPolicyRulesRequest) returns (ListPolicyRulesResponse);

  // CreatePolicyRule creates a new policy rule.
  // Requires: admin JWT.
  rpc CreatePolicyRule(CreatePolicyRuleRequest) returns (CreatePolicyRuleResponse);

  // GetPolicyRule returns a single policy rule by ID.
  // Requires: admin JWT.
  rpc GetPolicyRule(GetPolicyRuleRequest) returns (GetPolicyRuleResponse);

  // UpdatePolicyRule applies a partial update to a policy rule.
  // Requires: admin JWT.
  rpc UpdatePolicyRule(UpdatePolicyRuleRequest) returns (UpdatePolicyRuleResponse);

  // DeletePolicyRule permanently removes a policy rule.
  // Requires: admin JWT.
  rpc DeletePolicyRule(DeletePolicyRuleRequest) returns (DeletePolicyRuleResponse);
}
