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

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/manager/v1;manager";

// Request source type.
enum SourceType {
  // Scheduler service.
  SCHEDULER_SOURCE = 0;
  // Peer service.
  PEER_SOURCE = 1;
  // SeedPeer service.
  SEED_PEER_SOURCE = 2;
}

// SeedPeerCluster represents cluster of seed peer.
message SeedPeerCluster {
  // Cluster id.
  uint64 id = 1;
  // Cluster name.
  string name = 2;
  // Cluster biography.
  string bio = 3;
  // Cluster configuration.
  bytes config = 4;
}

// SeedPeer represents seed peer for network.
message SeedPeer {
  // Seed peer id.
  uint64 id = 1;
  // Seed peer hostname.
  string hostname = 2;
  // Seed peer type.
  string type = 3;
  // Seed peer idc.
  string idc = 5;
  // Seed peer location.
  string location = 7;
  // Seed peer ip.
  string ip = 8;
  // Seed peer grpc port.
  int32 port = 9;
  // Seed peer download port.
  int32 download_port = 10;
  // Seed peer state.
  string state = 11;
  // ID of the cluster to which the seed peer belongs.
  uint64 seed_peer_cluster_id = 12;
  // Cluster to which the seed peer belongs.
  SeedPeerCluster seed_peer_cluster = 13;
  // Schedulers included in seed peer.
  repeated Scheduler schedulers = 14;
  // Seed peer object storage port.
  int32 object_storage_port = 15;
}

// GetSeedPeerRequest represents request of GetSeedPeer.
message GetSeedPeerRequest {
  // Request source type.
  SourceType source_type = 1 [(validate.rules).enum.defined_only = true];
  // Seed peer hostname.
  string hostname = 2 [(validate.rules).string.hostname = true];
  // ID of the cluster to which the seed peer belongs.
  uint64 seed_peer_cluster_id = 3 [(validate.rules).uint64 = {gte: 1}];
  // Seed peer ip.
  string ip = 4 [(validate.rules).string = {ip: true, ignore_empty: true}];
}

// ListSeedPeersRequest represents request of ListSeedPeers.
message ListSeedPeersRequest {
  // Request source type.
  SourceType source_type = 1 [(validate.rules).enum.defined_only = true];
  // Source service hostname.
  string hostname = 2 [(validate.rules).string.hostname = true];
  // Source service ip.
  string ip = 3 [(validate.rules).string.ip = true];
  // Dfdaemon version.
  string version = 4 [(validate.rules).string = {min_len: 1, max_len: 1024, ignore_empty: true}];
  // Dfdaemon commit.
  string commit = 5 [(validate.rules).string = {min_len: 1, max_len: 1024, ignore_empty: true}];
}

// ListSeedPeersResponse represents response of ListSeedPeers.
message ListSeedPeersResponse {
  // Seed peers to which the source service belongs.
  repeated SeedPeer seed_peers = 1;
}

// UpdateSeedPeerRequest represents request of UpdateSeedPeer.
message UpdateSeedPeerRequest {
  // Request source type.
  SourceType source_type = 1 [(validate.rules).enum.defined_only = true];
  // Seed peer hostname.
  string hostname = 2 [(validate.rules).string.hostname = true];
  // Seed peer type.
  string type = 3 [(validate.rules).string = {in: ["super"]}];
  // Seed peer idc.
  string idc = 5 [(validate.rules).string = {min_len: 1, max_len: 1024, ignore_empty: true}];
  // Seed peer location.
  string location = 7 [(validate.rules).string = {max_len: 1024, ignore_empty: true}];
  // Seed peer ip.
  string ip = 8 [(validate.rules).string = {ip: true}];
  // Seed peer port.
  int32 port = 9 [(validate.rules).int32 = {gte: 1024, lt: 65535}];
  // Seed peer download port.
  int32 download_port = 10 [(validate.rules).int32 = {gte: 1024, lt: 65535}];
  // ID of the cluster to which the seed peer belongs.
  uint64 seed_peer_cluster_id = 11 [(validate.rules).uint64 = {gte: 1}];
  // Seed peer object storage port.
  int32 object_storage_port = 12 [(validate.rules).int32 = {gte: 1024, lt: 65535, ignore_empty: true}];
}

// SeedPeerCluster represents cluster of scheduler.
message SchedulerCluster {
  // Cluster id.
  uint64 id = 1;
  // Cluster name.
  string name = 2;
  // Cluster biography.
  string bio = 3;
  // Cluster config.
  bytes config = 4;
  // Cluster client config.
  bytes client_config = 5;
  // Cluster scopes.
  bytes scopes = 6;
}

// Scheduler represents scheduler for network.
message Scheduler {
  // Scheduler id.
  uint64 id = 1;
  // Scheduler hostname.
  string hostname = 2;
  // Deprecated: Do not use.
  string vips = 3;
  // Scheduler idc.
  string idc = 4;
  // Scheduler location.
  string location = 5;
  // Scheduler ip.
  string ip = 7;
  // Scheduler grpc port.
  int32 port = 8;
  // Scheduler state.
  string state = 9;
  // ID of the cluster to which the scheduler belongs.
  uint64 scheduler_cluster_id = 10;
  // Cluster to which the scheduler belongs.
  SchedulerCluster scheduler_cluster = 11;
  // Seed peers to which the scheduler belongs.
  repeated SeedPeer seed_peers = 13;
  // Feature flags of scheduler.
  bytes features = 14;
}

// GetSchedulerRequest represents request of GetScheduler.
message GetSchedulerRequest {
  // Request source type.
  SourceType source_type = 1 [(validate.rules).enum.defined_only = true];
  // Scheduler hostname.
  string hostname = 2 [(validate.rules).string.hostname = true];
  // ID of the cluster to which the scheduler belongs.
  uint64 scheduler_cluster_id = 3 [(validate.rules).uint64 = {gte: 1}];
  // Scheduler ip.
  string ip = 4 [(validate.rules).string = {ip: true, ignore_empty: true}];
}

// UpdateSchedulerRequest represents request of UpdateScheduler.
message UpdateSchedulerRequest {
  // Request source type.
  SourceType source_type = 1 [(validate.rules).enum.defined_only = true];
  // Scheduler hostname.
  string hostname = 2 [(validate.rules).string.hostname = true];
  // ID of the cluster to which the scheduler belongs.
  uint64 scheduler_cluster_id = 3 [(validate.rules).uint64 = {gte: 1}];
  // Deprecated: Do not use.
  string vips = 4 [(validate.rules).string = {min_len: 1, max_len: 1024, ignore_empty: true}];
  // Scheduler idc.
  string idc = 5 [(validate.rules).string = {min_len: 1, max_len: 1024, ignore_empty: true}];
  // Scheduler location.
  string location = 6 [(validate.rules).string = {min_len: 1, max_len: 1024, ignore_empty: true}];
  // Deprecated: Remove net_config params.
  bytes net_config = 7 [(validate.rules).bytes = {min_len: 1, ignore_empty: true}];
  // Scheduler ip.
  string ip = 8 [(validate.rules).string = {ip: true}];
  // Scheduler port.
  int32 port = 9 [(validate.rules).int32 = {gte: 1024, lt: 65535}];
}

// ListSchedulersRequest represents request of ListSchedulers.
message ListSchedulersRequest {
  // Request source type.
  SourceType source_type = 1 [(validate.rules).enum.defined_only = true];
  // Source service hostname.
  string hostname = 2 [(validate.rules).string.hostname = true];
  // Source service ip.
  string ip = 3 [(validate.rules).string.ip = true];
  // Source service host information.
  map<string, string> host_info = 5 [(validate.rules).map.ignore_empty = true];
  // Dfdaemon version.
  string version = 6 [(validate.rules).string = {min_len: 1, max_len: 1024, ignore_empty: true}];
  // Dfdaemon commit.
  string commit = 7 [(validate.rules).string = {min_len: 1, max_len: 1024, ignore_empty: true}];
}

// ListSchedulersResponse represents response of ListSchedulers.
message ListSchedulersResponse {
  // Schedulers to which the source service belongs.
  repeated Scheduler schedulers = 1;
}

// URLPriority represents config of url priority.
message URLPriority {
  // URL regex.
  string regex = 1 [(validate.rules).string = {min_len: 1}];
  // URL priority value.
  common.Priority value = 2;
}

// ApplicationPriority represents config of application priority.
message ApplicationPriority {
  // Priority value.
  common.Priority value = 1;
  // URL priority.
  repeated URLPriority urls = 2;
}

// Application represents config of application.
message Application {
  // Application id.
  uint64 id = 1 [(validate.rules).uint64 = {gte: 1}];
  // Application name.
  string name = 2 [(validate.rules).string = {min_len: 1, max_len: 1024}];
  // Application url.
  string url = 3 [(validate.rules).string.uri = true];
  // Application biography.
  string bio = 4;
  // Application priority.
  ApplicationPriority priority = 5 [(validate.rules).message.required = true];
}

// ListApplicationsRequest represents request of ListApplications.
message ListApplicationsRequest {
  // Request source type.
  SourceType source_type = 1 [(validate.rules).enum.defined_only = true];
  // Source service hostname.
  string hostname = 2 [(validate.rules).string.hostname = true];
  // Source service ip.
  string ip = 3 [(validate.rules).string.ip = true];
}

// ListApplicationsResponse represents response of ListApplications.
message ListApplicationsResponse {
  // Application configs.
  repeated Application applications = 1;
}

// KeepAliveRequest represents request of KeepAlive.
message KeepAliveRequest {
  // Request source type.
  SourceType source_type = 1 [(validate.rules).enum.defined_only = true];
  // Source service hostname.
  string hostname = 2 [(validate.rules).string.hostname = true];
  // ID of the cluster to which the source service belongs.
  uint64 cluster_id = 3 [(validate.rules).uint64 = {gte: 1}];
  // Source service ip.
  string ip = 4 [(validate.rules).string = {ip: true, ignore_empty: true}];
}

// Manager RPC Service.
service Manager {
  // Get SeedPeer and SeedPeer cluster configuration.
  rpc GetSeedPeer(GetSeedPeerRequest) returns(SeedPeer);

  // List acitve schedulers configuration.
  rpc ListSeedPeers(ListSeedPeersRequest)returns(ListSeedPeersResponse);

  // Update SeedPeer configuration.
  rpc UpdateSeedPeer(UpdateSeedPeerRequest) returns(SeedPeer);

  // Get Scheduler and Scheduler cluster configuration.
  rpc GetScheduler(GetSchedulerRequest)returns(Scheduler);

  // Update scheduler configuration.
  rpc UpdateScheduler(UpdateSchedulerRequest) returns(Scheduler);

  // List acitve schedulers configuration.
  rpc ListSchedulers(ListSchedulersRequest)returns(ListSchedulersResponse);

  // List applications configuration.
  rpc ListApplications(ListApplicationsRequest)returns(ListApplicationsResponse);

  // KeepAlive with manager.
  rpc KeepAlive(stream KeepAliveRequest)returns(google.protobuf.Empty);
}
