/*
 *     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 common.v2;

import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";

// SizeScope represents size scope of task.
enum SizeScope {
  // size > one piece size.
  NORMAL = 0;

  // 128 byte < size <= one piece size and be plain type.
  SMALL = 1;

  // size <= 128 byte and be plain type.
  TINY = 2;

  // size == 0 byte and be plain type.
  EMPTY = 3;
}

// TaskType represents type of task.
enum TaskType {
  // DFDAEMON is dfdeamon type of task,
  // dfdeamon task is a normal p2p task.
  DFDAEMON = 0;

  // DFCACHE is dfcache type of task,
  // dfcache task is a cache task, and the task url is fake url.
  // It can only be used for caching and cannot be downloaded back to source.
  DFCACHE = 1;

  // DFSTORE is dfstore type of task,
  // dfstore task is a persistent task in backend.
  DFSTORE = 2;
}

// TrafficType represents type of traffic.
enum TrafficType {
  // BACK_TO_SOURCE is to download traffic from the source.
  BACK_TO_SOURCE = 0;

  // REMOTE_PEER is to download traffic from the remote peer.
  REMOTE_PEER = 1;

  // LOCAL_PEER is to download traffic from the local peer.
  LOCAL_PEER = 2;
}

// Priority represents priority of application.
enum Priority {
  // LEVEL0 has no special meaning for scheduler.
  LEVEL0 = 0;

  // LEVEL1 represents the download task is forbidden,
  // and an error code is returned during the registration.
  LEVEL1 = 1;

  // LEVEL2 represents when the task is downloaded for the first time,
  // allow peers to download from the other peers,
  // but not back-to-source. When the task is not downloaded for
  // the first time, it is scheduled normally.
  LEVEL2 = 2;

  // LEVEL3 represents when the task is downloaded for the first time,
  // the normal peer is first to download back-to-source.
  // When the task is not downloaded for the first time, it is scheduled normally.
  LEVEL3 = 3;

  // LEVEL4 represents when the task is downloaded for the first time,
  // the weak peer is first triggered to back-to-source.
  // When the task is not downloaded for the first time, it is scheduled normally.
  LEVEL4 = 4;

  // LEVEL5 represents when the task is downloaded for the first time,
  // the strong peer is first triggered to back-to-source.
  // When the task is not downloaded for the first time, it is scheduled normally.
  LEVEL5 = 5;

  // LEVEL6 represents when the task is downloaded for the first time,
  // the super peer is first triggered to back-to-source.
  // When the task is not downloaded for the first time, it is scheduled normally.
  LEVEL6 = 6;
}

// Peer metadata.
message Peer {
  // Peer id.
  string id = 1;
  // Range is url range of request.
  optional Range range = 2;
  // Peer priority.
  Priority priority = 3;
  // Pieces of peer.
  repeated Piece pieces = 4;
  // Peer downloads costs time.
  google.protobuf.Duration cost = 5;
  // Peer state.
  string state = 6;
  // Task info.
  Task task = 7;
  // Host info.
  Host host = 8;
  // NeedBackToSource needs downloaded from source.
  bool need_back_to_source = 9;
  // Peer create time.
  google.protobuf.Timestamp created_at = 10;
  // Peer update time.
  google.protobuf.Timestamp updated_at = 11;
}

// Task metadata.
message Task {
  // Task id.
  string id = 1;
  // Task type.
  TaskType type = 2;
  // Download url.
  string url = 3;
  // Digest of the pieces digest, for example md5:xxx or sha256:yyy.
  optional string digest = 4;
  // URL tag identifies different task for same url.
  optional string tag = 5;
  // Application of task.
  optional string application = 6;
  // Filter url used to generate task id.
  repeated string filters = 7;
  // Task request headers.
  map<string, string> header = 8;
  // Task piece length.
  int32 piece_length = 9;
  // Task content length.
  int64 content_length = 10;
  // Task piece count.
  int32 piece_count = 11;
  // Task size scope.
  SizeScope size_scope = 12;
  // Pieces of task.
  repeated Piece pieces = 13;
  // Task state.
  string state = 14;
  // Task peer count.
  int32 peer_count = 15;
  // Task contains available peer.
  bool hasAvailablePeer = 16;
  // Task create time.
  google.protobuf.Timestamp created_at = 17;
  // Task update time.
  google.protobuf.Timestamp updated_at = 18;
}

// Host metadata.
message Host {
  // Host id.
  string id = 1;
  // Host type.
  uint32 type = 2;
  // Hostname.
  string hostname = 3;
  // Host ip.
  string ip = 4;
  // Port of grpc service.
  int32 port = 5;
  // Port of download server.
  int32 download_port = 6;
  // Host OS.
  string os = 7;
  // Host platform.
  string platform = 8;
  // Host platform family.
  string platform_family = 9;
  // Host platform version.
  string platform_version = 10;
  // Host kernel version.
  string kernel_version = 11;
  // CPU Stat.
  optional CPU cpu = 12;
  // Memory Stat.
  optional Memory memory = 13;
  // Network Stat.
  optional Network network = 14;
  // Disk Stat.
  optional Disk disk = 15;
  // Build information.
  optional Build build = 16;
  // ID of the cluster to which the host belongs.
  uint64 scheduler_cluster_id = 17;
  // Port of object storage server.
  int32 object_storage_port = 18;
}

// CPU Stat.
message CPU {
  // Number of logical cores in the system.
  uint32 logical_count = 1;
  // Number of physical cores in the system
  uint32 physical_count = 2;
  // Percent calculates the percentage of cpu used.
  double percent = 3;
  // Calculates the percentage of cpu used by process.
  double process_percent = 4;
  // CPUTimes contains the amounts of time the CPU has spent performing different kinds of work.
  optional CPUTimes times = 5;
}

// CPUTimes contains the amounts of time the CPU has spent performing different
// kinds of work. Time units are in seconds.
message CPUTimes {
  // CPU time of user.
  double user = 1;
  // CPU time of system.
  double system = 2;
  // CPU time of idle.
  double idle = 3;
  // CPU time of nice.
  double nice = 4;
  // CPU time of iowait.
  double iowait = 5;
  // CPU time of irq.
  double irq = 6;
  // CPU time of softirq.
  double softirq = 7;
  // CPU time of steal.
  double steal = 8;
  // CPU time of guest.
  double guest = 9;
  // CPU time of guest nice.
  double guest_nice = 10;
}

// Memory Stat.
message Memory {
  // Total amount of RAM on this system.
  uint64 total = 1;
  // RAM available for programs to allocate.
  uint64 available = 2;
  // RAM used by programs.
  uint64 used = 3;
  // Percentage of RAM used by programs.
  double used_percent = 4;
  // Calculates the percentage of memory used by process.
  double process_used_percent = 5;
  // This is the kernel's notion of free memory.
  uint64 free = 6;
}

// Network Stat.
message Network {
  // Return count of tcp connections opened and status is ESTABLISHED.
  uint32 tcp_connection_count = 1;
  // Return count of upload tcp connections opened and status is ESTABLISHED.
  uint32 upload_tcp_connection_count = 2;
  // Location path(area|country|province|city|...).
  optional string location = 3;
  // IDC where the peer host is located
  optional string idc = 4;
}

// Disk Stat.
message Disk {
  // Total amount of disk on the data path of dragonfly.
  uint64 total = 1;
  // Free amount of disk on the data path of dragonfly.
  uint64 free = 2;
  // Used amount of disk on the data path of dragonfly.
  uint64 used = 3;
  // Used percent of disk on the data path of dragonfly directory.
  double used_percent = 4;
  // Total amount of indoes on the data path of dragonfly directory.
  uint64 inodes_total = 5;
  // Used amount of indoes on the data path of dragonfly directory.
  uint64 inodes_used = 6;
  // Free amount of indoes on the data path of dragonfly directory.
  uint64 inodes_free = 7;
  // Used percent of indoes on the data path of dragonfly directory.
  double inodes_used_percent = 8;
}

// Build information.
message Build {
  // Git version.
  string git_version = 1;
  // Git commit.
  optional string git_commit = 2;
  // Golang version.
  optional string go_version = 3;
  // Rust version.
  optional string rust_version = 4;
  // Build platform.
  optional string platform = 5;
}

// Download information.
message Download {
  // Download url.
  string url = 1;
  // Digest of the pieces digest, for example md5:xxx or sha256:yyy.
  optional string digest = 2;
  // Range is url range of request.
  optional Range range = 3;
  // Task type.
  TaskType type = 4;
  // URL tag identifies different task for same url.
  optional string tag = 5;
  // Application of task.
  optional string application = 6;
  // Peer priority.
  Priority priority = 7;
  // Filter url used to generate task id.
  repeated string filters = 8;
  // Task request headers.
  map<string, string> header = 9;
  // Task piece length.
  int32 piece_length = 10;
  // File path to be exported.
  optional string output_path = 11;
  // Download timeout.
  optional google.protobuf.Duration timeout = 12;
  // Download rate limit in bytes per second.
  optional double download_rate_limit = 13;
  // NeedBackToSource needs downloaded from source.
  bool need_back_to_source = 14;
}

// Range represents download range.
message Range {
  // Start of range.
  int64 start = 1;
  // Length of range.
  int64 length = 2;
}

// Piece represents information of piece.
message Piece {
  // Piece number.
  int32 number = 1;
  // Parent peer id.
  optional string parent_id = 2;
  // Piece offset.
  uint64 offset = 3;
  // Piece length.
  uint64 length = 4;
  // Digest of the piece data, for example md5:xxx or sha256:yyy.
  string digest = 5;
  // Piece content.
  bytes content = 6;
  // Traffic type.
  optional TrafficType traffic_type = 7;
  // Downloading piece costs time.
  google.protobuf.Duration cost = 8;
  // Piece create time.
  google.protobuf.Timestamp created_at = 9;
}
