syntax = "proto3";

package armonik.api.grpc.v1.results;

import "google/protobuf/timestamp.proto";
import "result_status.proto";
import "results_fields.proto";
import "results_filters.proto";
import "sort_direction.proto";

option csharp_namespace = "ArmoniK.Api.gRPC.V1.Results";

/**
 * A raw result object.
 *
 * Used when a list or a single result is returned.
 */
message ResultRaw {
  string session_id = 1; /** The session ID. */
  string name = 2; /** The result name. Given by the client. */
  string owner_task_id = 3; /** The owner task ID. */
  result_status.ResultStatus status = 4; /** The result status. */
  google.protobuf.Timestamp created_at = 5; /** The result creation date. */
  google.protobuf.Timestamp completed_at = 6; /** The result completion date. */
  string result_id = 8; /** The result ID. Uniquely generated by the server. */
  int64 size = 9; /** The size of the Result Data. */
  string created_by = 10; /** The ID of the Task that as submitted this result.*/
}

/**
 * Request to list results.
 *
 * Use pagination, filtering and sorting.
 */
message ListResultsRequest {
  int32 page = 1; /** The page number. Start at 0. */
  int32 page_size = 2; /** The page size. */

  Filters filters = 3; /** The filters. */

  /**
   * Represents the sort object.
   */
  message Sort {
    ResultField field = 1; /** The field to use to sort results. */
    sort_direction.SortDirection direction = 2; /** The direction to use to sort results. */
  }

  /** The sort.
   *
   * Must be set for every request.
   */
  Sort sort = 4;
}

/**
 * Response to list results.
 *
 * Use pagination, filtering and sorting from the request.
 * Retunr a list of raw results.
 */
message ListResultsResponse {
  repeated ResultRaw results = 1; /** The list of raw results. */

  int32 page = 2; /** The page number. Start at 0. */
  int32 page_size = 3; /** The page size. */
  int32 total = 4; /** The total number of results. */
}

/**
 * Request to get an result.
 */
message GetResultRequest {
  string result_id = 1; /** Result id. Must fail when name is empty. **/
}

/**
 * Response to get an result.
 */
message GetResultResponse {
  ResultRaw result = 1; /** The result. */
}

/*
*  Request for getting the id of the task that should create this result
*/
message GetOwnerTaskIdRequest {
  string session_id = 1; /** The session ID. */
  repeated string result_id = 2; /** The list of result ID/name. */
}

/*
* Response for getting the id of the task that should create this result
*/
message GetOwnerTaskIdResponse {
  message MapResultTask {
    string result_id = 1; /** The result ID/name. */
    string task_id = 2; /** The owner task ID associated to the result. */
  }
  repeated MapResultTask result_task = 1;
  string session_id = 2; /** The session ID. */
}

/*
* Request for creating results without data
*/
message CreateResultsMetaDataRequest {
  /**
  * A result to create.
  */
  message ResultCreate {
    string name = 1; /** The result name. Given by the client. */
  }
  repeated ResultCreate results = 1; /** The list of results to create. */
  string session_id = 2; /** The session in which create results. */
}

/*
* Response for creating results without data
*/
message CreateResultsMetaDataResponse {
  repeated ResultRaw results = 1; /** The list of raw results that were created. */
}

/*
* Request for creating results with data
*/
message CreateResultsRequest {
  /**
  * A result to create.
  */
  message ResultCreate {
    string name = 1; /** The result name. Given by the client. */
    bytes data = 2; /** The actual data of the result. */
  }
  repeated ResultCreate results = 1; /** Results to create. */
  string session_id = 2; /** The session in which create results. */
}

/*
* Response for creating results without data
*/
message CreateResultsResponse {
  repeated ResultRaw results = 1; /** The raw results that were created. */
}

/*
* Request for uploading results data through stream.
* Data must be sent in multiple chunks.
* Only one result can be uploaded.
*/
message UploadResultDataRequest {
  /**
  * The metadata to identify the result to update.
  */
  message ResultIdentifier {
    string session_id = 1; /** The session of the result. */
    string result_id = 2; /** The ID of the result. */
  }

  /**
  * The possible messages that constitute a UploadResultDataRequest
  * They should be sent in the following order:
  * - id
  * - data_chunk (stream can have multiple data_chunk messages that represent data divided in several parts)
  *
  * Data chunk cannot exceed the size returned by the GetServiceConfiguration rpc method
  */
  oneof type {
    ResultIdentifier id = 1; /** The identifier of the result to which add data. */
    bytes data_chunk = 2; /** A chunk of data. */
  }
}

/*
* Response for creating results without data
*/
message UploadResultDataResponse {
  ResultRaw result = 1; /** The metadata of the updated result that was updated. */
}

/*
* Response for obtaining results service configuration
*/
message ResultsServiceConfigurationResponse {
  int32 data_chunk_max_size = 1; /** Maximum size supported by a data chunk for the result service*/
}

/*
* Request for getting a result
*/
message DownloadResultDataRequest {
  string session_id = 1; /** The session of the result. */
  string result_id = 2; /** The ID of the result. */
}

/*
* Response for creating results without data
*/
message DownloadResultDataResponse {
  /**
  * The possible messages that constitute a UploadResultDataRequest
  * Get the data chunks of the result
  */
  bytes data_chunk = 1; /** A chunk of data. */
}

/*
* Request deleting data from results results but keeping metadata
*/
message DeleteResultsDataRequest {
  string session_id = 1; /** The session of the results. */
  repeated string result_id = 2; /** The ID of the results to delete. */
}

/*
* Response deleting data from results results but keeping metadata
*/
message DeleteResultsDataResponse {
  string session_id = 1; /** The session of the results. */
  repeated string result_id = 2; /** The ID of the deleted results. */
}

/**
 * Request to watch result states
 * It contains the list of result ids you want to watch
 *   and some options to filter out some events.
 * Chunking is achieved by sending multiple messages with different result ids.
 * It is the responsability of the client to chunk the messages properly and avoid messages too large.
 */
message WatchResultRequest {
  // list of statuses to check results against for the initial fetch
  repeated result_status.ResultStatus fetch_statuses = 1;
  // list of statuses to check results against for the watch
  repeated result_status.ResultStatus watch_statuses = 2;
  // result ids to fetch/watch
  repeated string result_ids = 3;
}

/**
 * List of Result statuses
 * Result Ids are grouped by status. One message contains result Ids that have the same status.
 * Chunking is achieved by receiving several messages with the same status and the list of ids in multiple parts.
 * As chunking is implicit, there is no way to distinguish between chunked messages and actually separate messages.
 */
message WatchResultResponse {
  // Status of the results
  result_status.ResultStatus status = 1;
  // List of result ids that triggered the event
  repeated string result_ids = 2;
}
