/*
 *     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 dfdaemon;

import "pkg/apis/common/v1/common.proto";
import "google/protobuf/empty.proto";
import "validate/validate.proto";

option go_package = "d7y.io/api/v2/pkg/apis/dfdaemon/v1;dfdaemon";

message DownRequest{
  // Identify one downloading, the framework will fill it automatically.
  // Deprecated
  string uuid = 1;
  // Download file from the url, not only for http.
  string url = 2 [(validate.rules).string.uri = true];
  // Pieces will be written to output path directly,
  // at the same time, dfdaemon workspace also makes soft link to the output.
  string output = 3 [(validate.rules).string.min_len = 1];
  // Timeout duration.
  uint64 timeout = 4 [(validate.rules).uint64.gte = 0];
  // Rate limit in bytes per second.
  double limit = 5 [(validate.rules).double.gte = 0];
  // Disable back-to-source.
  bool disable_back_source = 6;
  // URL meta info.
  common.UrlMeta url_meta = 7 [(validate.rules).message.required = true];
  // User id.
  int64 uid = 10;
  // Group id.
  int64 gid = 11;
  // Keep original offset, used for ranged request, only available for hard link, otherwise will failed.
  bool keep_original_offset = 12;
  // Recursive download, when enabled, daemon will call resource list api to list and then recursive download each object.
  bool recursive = 13;
}

message DownResult{
  // Task id.
  string task_id = 2 [(validate.rules).string.min_len = 1];
  // Peer id.
  string peer_id = 3 [(validate.rules).string.min_len = 1];
  // Task has completed length.
  uint64 completed_length = 4 [(validate.rules).uint64.gte = 0];
  // Task has been completed.
  bool done = 5;
  // Task output. Used in recursive download.
  string output = 6;
}

message StatTaskRequest{
  // Download url.
  string url = 1 [(validate.rules).string.min_len = 1];
  // URL meta info.
  common.UrlMeta url_meta = 2 [(validate.rules).message.required = true];
  // Check local cache only.
  bool local_only = 3;
}

message ImportTaskRequest{
  // Download url.
  string url = 1 [(validate.rules).string.min_len = 1];
  // URL meta info.
  common.UrlMeta url_meta = 2 [(validate.rules).message.required = true];
  // File to be imported.
  string path = 3 [(validate.rules).string.min_len = 1];
  // Task type.
  common.TaskType type = 4;
}

message ExportTaskRequest{
  // Download url.
  string url = 1 [(validate.rules).string.min_len = 1];
  // Output path of downloaded file.
  string output = 2 [(validate.rules).string.min_len = 1];
  // Timeout duration.
  uint64 timeout = 3 [(validate.rules).uint64.gte = 0];
  // Rate limit in bytes per second.
  double limit = 4 [(validate.rules).double.gte = 0];
  // URL meta info.
  common.UrlMeta url_meta = 5 [(validate.rules).message.required = true];
  // User id.
  int64 uid = 7;
  // Group id.
  int64 gid = 8;
  // Only export from local storage.
  bool local_only = 9;
}

message DeleteTaskRequest{
  // Download url.
  string url = 1 [(validate.rules).string.min_len = 1];
  // URL meta info.
  common.UrlMeta url_meta = 2 [(validate.rules).message.required = true];
}

// PeerState represents state of peer task.
enum PeerState {
  Unknown = 0;
  Running = 1;
  Success = 2;
  Failed = 3;
  Deleted = 4;
}

// PeerMetadata represents metadata of a peer task.
message PeerMetadata {
  string task_id = 1;
  string peer_id = 2;
  PeerState state = 3;
}

// PeerExchangeData represents metadata of peer tasks.
message PeerExchangeData {
  repeated PeerMetadata PeerMetadatas= 1;
}

// Daemon Client RPC Service
service Daemon{
  // Trigger client to download file
  rpc Download(DownRequest) returns(stream DownResult);
  // Get piece tasks from other peers
  rpc GetPieceTasks(common.PieceTaskRequest)returns(common.PiecePacket);
  // Check daemon health
  rpc CheckHealth(google.protobuf.Empty)returns(google.protobuf.Empty);
  // Sync piece tasks with other peers
  rpc SyncPieceTasks(stream common.PieceTaskRequest)returns(stream common.PiecePacket);
  // Check if given task exists in P2P cache system
  rpc StatTask(StatTaskRequest) returns(google.protobuf.Empty);
  // Import the given file into P2P cache system
  rpc ImportTask(ImportTaskRequest) returns(google.protobuf.Empty);
  // Export or download file from P2P cache system
  rpc ExportTask(ExportTaskRequest) returns(google.protobuf.Empty);
  // Delete file from P2P cache system
  rpc DeleteTask(DeleteTaskRequest) returns(google.protobuf.Empty);
  // LeaveHost releases host in scheduler.
  rpc LeaveHost(google.protobuf.Empty)returns(google.protobuf.Empty);
  // Exchange peers between daemons
  rpc PeerExchange(stream PeerExchangeData)returns(stream PeerExchangeData);
}
