/*
 *     Copyright 2022 The Dragonfly Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

syntax = "proto3";

package scheduler.v2;

import "common.proto";
import "errordetails.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";

// RegisterPeerRequest represents peer registered request of AnnouncePeerRequest.
message RegisterPeerRequest {
  // Download information.
  common.v2.Download download = 1;
}

// DownloadPeerStartedRequest represents peer download started request of AnnouncePeerRequest.
message DownloadPeerStartedRequest {
}

// DownloadPeerBackToSourceStartedRequest represents peer download back-to-source started request of AnnouncePeerRequest.
message DownloadPeerBackToSourceStartedRequest {
  // The description of the back-to-source reason.
  optional string description = 1;
}

// ReschedulePeerRequest represents reschedule request of AnnouncePeerRequest.
message ReschedulePeerRequest {
  // Candidate parent ids.
  repeated common.v2.Peer candidate_parents = 1;
  // The description of the reschedule reason.
  optional string description = 2;
}

// DownloadPeerFinishedRequest represents peer download finished request of AnnouncePeerRequest.
message DownloadPeerFinishedRequest {
  // Total content length.
  uint64 content_length = 1;
  // Total piece count.
  uint32 piece_count = 2;
}

// DownloadPeerBackToSourceFinishedRequest represents peer download back-to-source finished request of AnnouncePeerRequest.
message DownloadPeerBackToSourceFinishedRequest {
  // Total content length.
  uint64 content_length = 1;
  // Total piece count.
  uint32 piece_count = 2;
}

// DownloadPeerFailedRequest represents peer download failed request of AnnouncePeerRequest.
message DownloadPeerFailedRequest {
  // The description of the download failed.
  optional string description = 1;
}

// DownloadPeerBackToSourceFailedRequest represents peer download back-to-source failed request of AnnouncePeerRequest.
message DownloadPeerBackToSourceFailedRequest {
  // The description of the download back-to-source failed.
  optional string description = 1;
}

// DownloadPieceFinishedRequest represents piece download finished request of AnnouncePeerRequest.
message DownloadPieceFinishedRequest {
  // Piece info.
  common.v2.Piece piece = 1;
}

// DownloadPieceBackToSourceFinishedRequest represents piece download back-to-source finished request of AnnouncePeerRequest.
message DownloadPieceBackToSourceFinishedRequest {
  // Piece info.
  common.v2.Piece piece = 1;
}

// DownloadPieceFailedRequest downloads piece failed request of AnnouncePeerRequest.
message DownloadPieceFailedRequest {
  // Piece number.
  optional uint32 piece_number = 1;
  // Parent id.
  string parent_id = 2;
  // Temporary indicates whether the error is temporary.
  bool temporary = 3;
}

// DownloadPieceBackToSourceFailedRequest downloads piece back-to-source failed request of AnnouncePeerRequest.
message DownloadPieceBackToSourceFailedRequest {
  // Piece number.
  optional uint32 piece_number = 1;

  oneof response {
    errordetails.v2.Backend backend = 2;
    errordetails.v2.Unknown unknown = 3;
  }
}

// AnnouncePeerRequest represents request of AnnouncePeer.
message AnnouncePeerRequest {
  // Host id.
  string host_id = 1;
  // Task id.
  string task_id = 2;
  // Peer id.
  string peer_id = 3;

  oneof request {
    RegisterPeerRequest register_peer_request = 4;
    DownloadPeerStartedRequest download_peer_started_request = 5;
    DownloadPeerBackToSourceStartedRequest download_peer_back_to_source_started_request = 6;
    ReschedulePeerRequest reschedule_peer_request = 7;
    DownloadPeerFinishedRequest download_peer_finished_request = 8;
    DownloadPeerBackToSourceFinishedRequest download_peer_back_to_source_finished_request = 9;
    DownloadPeerFailedRequest download_peer_failed_request = 10;
    DownloadPeerBackToSourceFailedRequest download_peer_back_to_source_failed_request = 11;
    DownloadPieceFinishedRequest download_piece_finished_request = 12;
    DownloadPieceBackToSourceFinishedRequest download_piece_back_to_source_finished_request = 13;
    DownloadPieceFailedRequest download_piece_failed_request = 14;
    DownloadPieceBackToSourceFailedRequest download_piece_back_to_source_failed_request = 15;
  }
}

// EmptyTaskResponse represents empty task response of AnnouncePeerResponse.
message EmptyTaskResponse {
}

// NormalTaskResponse represents normal task response of AnnouncePeerResponse.
message NormalTaskResponse {
  // Candidate parents.
  repeated common.v2.Peer candidate_parents = 1;
}

// NeedBackToSourceResponse represents need back-to-source response of AnnouncePeerResponse.
message NeedBackToSourceResponse {
  // The description of the back-to-source reason.
  optional string description = 1;
}

// AnnouncePeerResponse represents response of AnnouncePeer.
message AnnouncePeerResponse {
  oneof response {
    EmptyTaskResponse empty_task_response = 1;
    NormalTaskResponse normal_task_response = 2;
    NeedBackToSourceResponse need_back_to_source_response = 3;
  }
}

// StatPeerRequest represents request of StatPeer.
message StatPeerRequest {
  // Host id.
  string host_id = 1;
  // Task id.
  string task_id = 2;
  // Peer id.
  string peer_id = 3;
}

// DeletePeerRequest represents request of DeletePeer.
message DeletePeerRequest {
  // Host id.
  string host_id = 1;
  // Task id.
  string task_id = 2;
  // Peer id.
  string peer_id = 3;
}

// StatTaskRequest represents request of StatTask.
message StatTaskRequest {
  // Host id.
  string host_id = 1;
  // Task id.
  string task_id = 2;
}

// DeleteTaskRequest represents request of DeleteTask.
message DeleteTaskRequest {
  // Host id.
  string host_id = 1;
  // Task id.
  string task_id = 2;
}

// AnnounceHostRequest represents request of AnnounceHost.
message AnnounceHostRequest {
  // Host information.
  common.v2.Host host = 1;
  // The interval between dfdaemon announces to scheduler.
  optional google.protobuf.Duration interval = 2;
}

// ListHostsResponse represents response of ListHosts.
message ListHostsResponse {
  // Hosts info.
  repeated common.v2.Host hosts = 1;
}

// DeleteHostRequest represents request of DeleteHost.
message DeleteHostRequest{
  // Host id.
  string host_id = 1;
}

// RegisterPersistentCachePeerRequest represents persistent cache peer registered request of AnnouncePersistentCachePeerRequest.
message RegisterPersistentCachePeerRequest {
  // Persistent represents whether the persistent cache task is persistent.
  // If the persistent cache task is persistent, the persistent cache peer will
  // not be deleted when dfdaemon runs garbage collection.
  bool persistent = 1;
  // Tag is used to distinguish different persistent cache tasks.
  optional string tag = 2;
  // Application of task.
  optional string application = 3;
  // Task piece length, the value needs to be greater than or equal to 4194304(4MiB).
  uint64 piece_length = 4;
  // File path to be exported.
  optional string output_path = 5;
  // Download timeout.
  optional google.protobuf.Duration timeout = 6;
}

// DownloadPersistentCachePeerStartedRequest represents persistent cache peer download started request of AnnouncePersistentCachePeerRequest.
message DownloadPersistentCachePeerStartedRequest {
}

// ReschedulePersistentCachePeerRequest represents reschedule request of AnnouncePersistentCachePeerRequest.
message ReschedulePersistentCachePeerRequest {
  // Candidate parent ids.
  repeated common.v2.PersistentCachePeer candidate_parents = 1;

  // The description of the reschedule reason.
  optional string description = 2;
}

// DownloadPersistentCachePeerFinishedRequest represents persistent cache peer download finished request of AnnouncePersistentCachePeerRequest.
message DownloadPersistentCachePeerFinishedRequest {
  // Total piece count.
  uint32 piece_count = 1;
}

// DownloadPersistentCachePeerFailedRequest represents persistent cache peer download failed request of AnnouncePersistentCachePeerRequest.
message DownloadPersistentCachePeerFailedRequest {
  // The description of the download failed.
  optional string description = 1;
}

// AnnouncePersistentCachePeerRequest represents request of AnnouncePersistentCachePeer.
message AnnouncePersistentCachePeerRequest {
  // Host id.
  string host_id = 1;
  // Task id.
  string task_id = 2;
  // Peer id.
  string peer_id = 3;

  oneof request {
    RegisterPersistentCachePeerRequest register_persistent_cache_peer_request = 4;
    DownloadPersistentCachePeerStartedRequest download_persistent_cache_peer_started_request = 5;
    ReschedulePersistentCachePeerRequest reschedule_persistent_cache_peer_request = 6;
    DownloadPersistentCachePeerFinishedRequest download_persistent_cache_peer_finished_request = 7;
    DownloadPersistentCachePeerFailedRequest download_persistent_cache_peer_failed_request = 8;
    DownloadPieceFinishedRequest download_piece_finished_request = 9;
    DownloadPieceFailedRequest download_piece_failed_request = 10;
  }
}

// EmptyPersistentCacheTaskResponse represents empty persistent cache task response of AnnouncePersistentCachePeerResponse.
message EmptyPersistentCacheTaskResponse {
}

// NormalPersistentCacheTaskResponse represents normal persistent cache task response of AnnouncePersistentCachePeerResponse.
message NormalPersistentCacheTaskResponse {
  // Candidate parents.
  repeated common.v2.PersistentCachePeer candidate_cache_parents = 1;
}

// AnnouncePersistentCachePeerResponse represents response of AnnouncePersistentCachePeer.
message AnnouncePersistentCachePeerResponse {
  oneof response {
    EmptyPersistentCacheTaskResponse empty_persistent_cache_task_response = 1;
    NormalPersistentCacheTaskResponse normal_persistent_cache_task_response = 2;
  }
}

// StatPersistentCachePeerRequest represents request of StatPersistentCachePeer.
message StatPersistentCachePeerRequest {
  // Host id.
  string host_id = 1;
  // Task id.
  string task_id = 2;
  // Peer id.
  string peer_id = 3;
}

// DeletePersistentCachePeerRequest represents request of DeletePersistentCachePeer.
message DeletePersistentCachePeerRequest {
  // Host id.
  string host_id = 1;
  // Task id.
  string task_id = 2;
  // Peer id.
  string peer_id = 3;
}

// UploadPersistentCacheTaskStartedRequest represents upload persistent cache task started request of UploadPersistentCacheTaskStarted.
message UploadPersistentCacheTaskStartedRequest {
  // Host id.
  string host_id = 1;
  // Task id.
  string task_id = 2;
  // Peer id.
  string peer_id = 3;
  // Replica count of the persistent cache task.
  uint64 persistent_replica_count = 4;
  // Tag is used to distinguish different persistent cache tasks.
  optional string tag = 5;
  // Application of task.
  optional string application = 6;
  // Task piece length, the value needs to be greater than or equal to 4194304(4MiB).
  uint64 piece_length = 7;
  // Task content length.
  uint64 content_length = 8;
  // Task piece count.
  uint32 piece_count = 9;
  // TTL of the persistent cache task.
  google.protobuf.Duration ttl = 10;
}

// UploadPersistentCacheTaskFinishedRequest represents upload persistent cache task finished request of UploadPersistentCacheTaskFinished.
message UploadPersistentCacheTaskFinishedRequest {
  // Host id.
  string host_id = 1;
  // Task id.
  string task_id = 2;
  // Peer id.
  string peer_id = 3;
}

// UploadPersistentCacheTaskFailedRequest represents upload persistent cache task failed request of UploadPersistentCacheTaskFailed.
message UploadPersistentCacheTaskFailedRequest {
  // Host id.
  string host_id = 1;
  // Task id.
  string task_id = 2;
  // Peer id.
  string peer_id = 3;
  // The description of the upload failed.
  optional string description = 4;
}

// StatPersistentCacheTaskRequest represents request of StatPersistentCacheTask.
message StatPersistentCacheTaskRequest {
  // Host id.
  string host_id = 1;
  // Task id.
  string task_id = 2;
}

// DeletePersistentCacheTaskRequest represents request of DeletePersistentCacheTask.
message DeletePersistentCacheTaskRequest {
  // Host id.
  string host_id = 1;
  // Task id.
  string task_id = 2;
}

// Scheduler RPC Service.
service Scheduler {
  // AnnouncePeer announces peer to scheduler.
  rpc AnnouncePeer(stream AnnouncePeerRequest) returns(stream AnnouncePeerResponse);

  // Checks information of peer.
  rpc StatPeer(StatPeerRequest)returns(common.v2.Peer);

  // DeletePeer releases peer in scheduler.
  rpc DeletePeer(DeletePeerRequest)returns(google.protobuf.Empty);

  // Checks information of task.
  rpc StatTask(StatTaskRequest)returns(common.v2.Task);

  // DeleteTask releases task in scheduler.
  rpc DeleteTask(DeleteTaskRequest)returns(google.protobuf.Empty);

  // AnnounceHost announces host to scheduler.
  rpc AnnounceHost(AnnounceHostRequest)returns(google.protobuf.Empty);

  // ListHosts lists hosts in scheduler.
  rpc ListHosts(google.protobuf.Empty)returns(ListHostsResponse);

  // DeleteHost releases host in scheduler.
  rpc DeleteHost(DeleteHostRequest)returns(google.protobuf.Empty);

  // AnnouncePersistentCachePeer announces persistent cache peer to scheduler.
  rpc AnnouncePersistentCachePeer(stream AnnouncePersistentCachePeerRequest) returns(stream AnnouncePersistentCachePeerResponse);

  // Checks information of persistent cache peer.
  rpc StatPersistentCachePeer(StatPersistentCachePeerRequest)returns(common.v2.PersistentCachePeer);

  // DeletePersistentCachePeer releases persistent cache peer in scheduler.
  rpc DeletePersistentCachePeer(DeletePersistentCachePeerRequest)returns(google.protobuf.Empty);

  // UploadPersistentCacheTaskStarted uploads persistent cache task started to scheduler.
  rpc UploadPersistentCacheTaskStarted(UploadPersistentCacheTaskStartedRequest)returns(google.protobuf.Empty);

  // UploadPersistentCacheTaskFinished uploads persistent cache task finished to scheduler.
  rpc UploadPersistentCacheTaskFinished(UploadPersistentCacheTaskFinishedRequest)returns(common.v2.PersistentCacheTask);

  // UploadPersistentCacheTaskFailed uploads persistent cache task failed to scheduler.
  rpc UploadPersistentCacheTaskFailed(UploadPersistentCacheTaskFailedRequest)returns(google.protobuf.Empty);

  // Checks information of persistent cache task.
  rpc StatPersistentCacheTask(StatPersistentCacheTaskRequest)returns(common.v2.PersistentCacheTask);

  // DeletePersistentCacheTask releases persistent cache task in scheduler.
  rpc DeletePersistentCacheTask(DeletePersistentCacheTaskRequest)returns(google.protobuf.Empty);
}
