syntax = "proto3";

option csharp_namespace = "CloudServicesCrud";

package cloudservicescrud;

import "google/protobuf/struct.proto";

service DynamicCrudService {
  rpc GetAll        (GetAllRequest)     returns (CrudResponse);
  rpc GetById       (GetByIdRequest)    returns (CrudResponse);
  rpc Create        (CreateRequest)     returns (CrudResponse);
  rpc Update        (UpdateRequest)     returns (CrudResponse);
  rpc Delete        (DeleteRequest)     returns (CrudResponse);
  rpc Search        (SearchRequest)     returns (CrudResponse);
  rpc Count         (SearchRequest)     returns (CountResponse);
  rpc BulkCreate    (BulkCreateRequest) returns (BulkCreateResponse);
  rpc Upsert        (UpsertRequest)     returns (CrudResponse);
  rpc ExecuteBatch  (BatchRequest)      returns (BatchResponse);
  rpc BulkUpdate    (BulkUpdateRequest) returns (BulkWriteResponse);
  rpc BulkDelete    (BulkDeleteRequest) returns (BulkWriteResponse);
  rpc GetFields     (GetFieldsRequest)  returns (GetFieldsResponse);
}

// ---------- Mensajes auxiliares ----------

message OrderBy {
  string field     = 1;  // nombre de propiedad C#
  string direction = 2;  // "asc" | "desc"
}

message FilterCondition {
  string field  = 1;
  string op     = 2;  // eq, ne, gt, gte, lt, lte, like, in, between, isnull, isnotnull
  string value  = 3;
  string value2 = 4;  // solo para between
}

// ---------- Requests ----------

message GetAllRequest {
  string model              = 1;
  repeated string columns   = 2;
  int32 limit               = 3;  // máx registros; 0 = default servidor (1000)
  repeated OrderBy order_by = 4;  // opcional
}

message GetByIdRequest {
  string model            = 1;
  string id               = 2;
  repeated string columns = 3;
}

message CreateRequest {
  string                model = 1;
  google.protobuf.Struct data = 2;
}

message UpdateRequest {
  string                model = 1;
  string                id    = 2;
  google.protobuf.Struct data = 3;
}

message DeleteRequest {
  string model = 1;
  string id    = 2;
}

message SearchRequest {
  string model                  = 1;
  repeated FilterCondition and  = 2;  // condiciones combinadas con AND
  repeated FilterCondition or   = 3;  // condiciones combinadas con OR
  repeated string columns       = 4;
  string search_term            = 5;  // texto libre en columnas string (opcional)
  int32  page                   = 6;  // 0 = sin paginación, retorna todo
  int32  page_size              = 7;
  repeated OrderBy order_by     = 8;  // opcional
}

message BulkCreateRequest {
  string                        model   = 1;
  repeated google.protobuf.Struct records = 2;
}

message UpsertRequest {
  string                model           = 1;
  google.protobuf.Struct data            = 2;
  repeated string        conflict_fields = 3;
}

message BatchOperation {
  string                 type            = 1;  // "create" | "update" | "delete" | "upsert"
  string                 model           = 2;
  string                 id              = 3;  // para update y delete
  google.protobuf.Struct data            = 4;  // para create, update y upsert
  repeated string        conflict_fields = 5;  // para upsert
}

message BatchRequest {
  repeated BatchOperation operations = 1;
}

message BulkUpdateRequest {
  string                 model = 1;
  repeated FilterCondition and = 2;
  repeated FilterCondition or  = 3;
  google.protobuf.Struct data  = 4;
}

message BulkDeleteRequest {
  string model                  = 1;
  repeated FilterCondition and  = 2;
  repeated FilterCondition or   = 3;
}

message BulkWriteResponse {
  bool   success  = 1;
  string message  = 2;
  string status   = 3;
  int32  affected = 4;
  string detail   = 5;
}

message GetFieldsRequest {
  string model = 1;
}

// ---------- Responses ----------

message CountResponse {
  bool   success = 1;
  string message = 2;
  int32  total   = 3;
}

message BulkCreateResponse {
  bool            success      = 1;
  string          message      = 2;
  string          status       = 3;
  int32           inserted     = 4;
  repeated string inserted_ids = 5;
  string          detail       = 6;
}

message BatchOperationResult {
  bool   success     = 1;
  string message     = 2;
  string status      = 3;
  string inserted_id = 4;
  int32  index       = 5;
}

message BatchResponse {
  bool                          success  = 1;
  string                        message  = 2;
  string                        status   = 3;
  repeated BatchOperationResult results  = 4;
}

message FieldInfo {
  string name     = 1;  // nombre de propiedad C#
  string type     = 2;  // tipo: String, Int32, Boolean, DateTime, etc.
  bool   nullable = 3;
  string column   = 4;  // nombre real de la columna en la DB
}

message GetFieldsResponse {
  bool               success = 1;
  string             message = 2;
  repeated FieldInfo fields  = 3;
}

// ---------- Respuesta homologada ----------

message CrudResponse {
  bool                  success     = 1;
  string                message     = 2;
  google.protobuf.Value data        = 3;  // objeto o array nativo protobuf
  string                detail      = 4;  // detalle de error
  string                status      = 5;  // "success" | "info" | "error"
  string                inserted_id = 6;  // poblado en Create y Upsert (insert)
  int32                 total       = 7;  // total de registros cuando page > 0
  int32                 page        = 8;
  int32                 page_size   = 9;
}
