syntax = "proto3";

package creditservice.v1;

option go_package = "github.com/cloud/creditservice/proto/creditservice/v1;creditservicev1";

import "google/protobuf/timestamp.proto";

// ============================================================================
// CreditService - Minimal credit/quota control for Photon admission flows
// ============================================================================

service CreditService {
  // Wallet operations for simple top-up and balance tracking
  rpc GetWallet(GetWalletRequest) returns (GetWalletResponse);
  rpc CreateWallet(CreateWalletRequest) returns (CreateWalletResponse);
  rpc TopUp(TopUpRequest) returns (TopUpResponse);
  rpc GetTransactions(GetTransactionsRequest) returns (GetTransactionsResponse);

  // Admission control used by gateway and resource services before creation
  rpc CheckQuota(CheckQuotaRequest) returns (CheckQuotaResponse);
  rpc ReserveCredits(ReserveCreditsRequest) returns (ReserveCreditsResponse);
  rpc CommitReservation(CommitReservationRequest) returns (CommitReservationResponse);
  rpc ReleaseReservation(ReleaseReservationRequest) returns (ReleaseReservationResponse);

  // Internal billing hook for simple batch charging, not a full billing product
  rpc ProcessBilling(ProcessBillingRequest) returns (ProcessBillingResponse);

  // Quota management for control-plane enforcement
  rpc SetQuota(SetQuotaRequest) returns (SetQuotaResponse);
  rpc GetQuota(GetQuotaRequest) returns (GetQuotaResponse);
  rpc ListQuotas(ListQuotasRequest) returns (ListQuotasResponse);
}

// ============================================================================
// Core Types
// ============================================================================

// Wallet represents a project's lightweight credit account.
message Wallet {
  string project_id = 1;
  string org_id = 2;
  // Balance in smallest credit unit (e.g., 100 = 1.00 credits)
  int64 balance = 3;
  // Reserved credits (pending reservations)
  int64 reserved = 4;
  // Total credits ever deposited
  int64 total_deposited = 5;
  // Total credits consumed
  int64 total_consumed = 6;
  WalletStatus status = 7;
  google.protobuf.Timestamp created_at = 8;
  google.protobuf.Timestamp updated_at = 9;
}

enum WalletStatus {
  WALLET_STATUS_UNSPECIFIED = 0;
  WALLET_STATUS_ACTIVE = 1;
  WALLET_STATUS_SUSPENDED = 2;  // Insufficient balance
  WALLET_STATUS_CLOSED = 3;
}

// Transaction represents a credit movement
message Transaction {
  string id = 1;
  string project_id = 2;
  TransactionType type = 3;
  int64 amount = 4;
  int64 balance_after = 5;
  string description = 6;
  string resource_id = 7;  // Optional: related resource
  google.protobuf.Timestamp created_at = 8;
}

enum TransactionType {
  TRANSACTION_TYPE_UNSPECIFIED = 0;
  TRANSACTION_TYPE_TOP_UP = 1;          // Credit addition
  TRANSACTION_TYPE_RESERVATION = 2;     // Temporary hold
  TRANSACTION_TYPE_CHARGE = 3;          // Actual consumption
  TRANSACTION_TYPE_RELEASE = 4;         // Reservation release
  TRANSACTION_TYPE_REFUND = 5;          // Credit return
  TRANSACTION_TYPE_BILLING_CHARGE = 6;  // Periodic billing
}

// Reservation represents a credit hold (2-phase commit)
message Reservation {
  string id = 1;
  string project_id = 2;
  int64 amount = 3;
  ReservationStatus status = 4;
  string description = 5;
  google.protobuf.Timestamp expires_at = 6;
  google.protobuf.Timestamp created_at = 7;
}

enum ReservationStatus {
  RESERVATION_STATUS_UNSPECIFIED = 0;
  RESERVATION_STATUS_PENDING = 1;
  RESERVATION_STATUS_COMMITTED = 2;
  RESERVATION_STATUS_RELEASED = 3;
  RESERVATION_STATUS_EXPIRED = 4;
}

// Quota represents resource limits per project
message Quota {
  string project_id = 1;
  ResourceType resource_type = 2;
  int64 limit = 3;
  int64 current_usage = 4;
}

enum ResourceType {
  RESOURCE_TYPE_UNSPECIFIED = 0;
  RESOURCE_TYPE_VM_INSTANCE = 1;
  RESOURCE_TYPE_VM_CPU = 2;
  RESOURCE_TYPE_VM_MEMORY_GB = 3;
  RESOURCE_TYPE_STORAGE_GB = 4;
  RESOURCE_TYPE_NETWORK_PORT = 5;
  RESOURCE_TYPE_LOAD_BALANCER = 6;
  RESOURCE_TYPE_DNS_ZONE = 7;
  RESOURCE_TYPE_DNS_RECORD = 8;
  RESOURCE_TYPE_K8S_CLUSTER = 9;
  RESOURCE_TYPE_K8S_NODE = 10;
}

// ============================================================================
// Wallet Operations
// ============================================================================

message GetWalletRequest {
  string project_id = 1;
}

message GetWalletResponse {
  Wallet wallet = 1;
}

message CreateWalletRequest {
  string project_id = 1;
  string org_id = 2;
  int64 initial_balance = 3;  // Optional initial credit
}

message CreateWalletResponse {
  Wallet wallet = 1;
}

message TopUpRequest {
  string project_id = 1;
  int64 amount = 2;
  string description = 3;  // e.g., "Payment ID: xxx"
}

message TopUpResponse {
  Wallet wallet = 1;
  Transaction transaction = 2;
}

message GetTransactionsRequest {
  string project_id = 1;
  // Pagination
  int32 page_size = 2;
  string page_token = 3;
  // Filters
  TransactionType type_filter = 4;
  google.protobuf.Timestamp start_time = 5;
  google.protobuf.Timestamp end_time = 6;
}

message GetTransactionsResponse {
  repeated Transaction transactions = 1;
  string next_page_token = 2;
}

// ============================================================================
// Admission Control
// ============================================================================

message CheckQuotaRequest {
  string project_id = 1;
  ResourceType resource_type = 2;
  int32 quantity = 3;
  int64 estimated_cost = 4;  // Optional: estimated credit cost
}

message CheckQuotaResponse {
  bool allowed = 1;
  string reason = 2;  // Reason if not allowed
  int64 available_balance = 3;
  int64 available_quota = 4;
}

message ReserveCreditsRequest {
  string project_id = 1;
  int64 amount = 2;
  string description = 3;
  string resource_type = 4;  // For tracking
  int32 ttl_seconds = 5;     // Reservation TTL (default: 300)
}

message ReserveCreditsResponse {
  Reservation reservation = 1;
}

message CommitReservationRequest {
  string reservation_id = 1;
  int64 actual_amount = 2;  // May differ from reserved amount
  string resource_id = 3;   // Created resource ID for tracking
}

message CommitReservationResponse {
  Transaction transaction = 1;
  Wallet wallet = 2;
}

message ReleaseReservationRequest {
  string reservation_id = 1;
  string reason = 2;  // Why released (e.g., "creation failed")
}

message ReleaseReservationResponse {
  bool success = 1;
}

// ============================================================================
// Billing
// ============================================================================

message ProcessBillingRequest {
  string project_id = 1;  // Empty = process all projects
  google.protobuf.Timestamp billing_period_start = 2;
  google.protobuf.Timestamp billing_period_end = 3;
}

message ProcessBillingResponse {
  int32 projects_processed = 1;
  int64 total_charged = 2;
  repeated BillingResult results = 3;
}

message BillingResult {
  string project_id = 1;
  int64 amount_charged = 2;
  bool success = 3;
  string error = 4;
}

// ============================================================================
// Quota Management
// ============================================================================

message SetQuotaRequest {
  string project_id = 1;
  ResourceType resource_type = 2;
  int64 limit = 3;
}

message SetQuotaResponse {
  Quota quota = 1;
}

message GetQuotaRequest {
  string project_id = 1;
  ResourceType resource_type = 2;
}

message GetQuotaResponse {
  Quota quota = 1;
}

message ListQuotasRequest {
  string project_id = 1;
}

message ListQuotasResponse {
  repeated Quota quotas = 1;
}
