syntax = "proto3";

package api;

option go_package = "github.com/psviderski/uncloud/internal/machine/api/pb";

import "google/protobuf/empty.proto";
import "internal/machine/api/pb/common.proto";

service Machine {
  // CheckPrerequisites verifies if the machine meets all necessary system requirements to participate in the cluster.
  rpc CheckPrerequisites(google.protobuf.Empty) returns (CheckPrerequisitesResponse);
  rpc InitCluster(InitClusterRequest) returns (InitClusterResponse);
  rpc JoinCluster(JoinClusterRequest) returns (google.protobuf.Empty);
  rpc Token(google.protobuf.Empty) returns (TokenResponse);
  rpc Inspect(google.protobuf.Empty) returns (MachineInfo);
  // Reset restores the machine to a clean state, removing all cluster-related configuration and data.
  rpc Reset(ResetRequest) returns (google.protobuf.Empty);

  rpc InspectService(InspectServiceRequest) returns (InspectServiceResponse);
}

message MachineInfo {
  string id = 1;
  string name = 2;
  NetworkConfig network = 3;
  IP public_ip = 4;
}

message NetworkConfig {
  IPPrefix subnet = 1;
  IP management_ip = 2;
  repeated IPPort endpoints = 3;
  bytes public_key = 4;
}

message CheckPrerequisitesResponse {
  // Overall status of the checks.
  bool satisfied = 1;
  // Error message if not satisfied (empty if all checks pass).
  string error = 2;
}

message InitClusterRequest {
  string machineName = 1;
  IPPrefix network = 2;

  oneof public_ip_config {
    IP public_ip = 3;
    bool public_ip_auto = 4;
  }
}

message InitClusterResponse {
  MachineInfo machine = 1;
}

message JoinClusterRequest {
  MachineInfo machine = 1;
  repeated MachineInfo other_machines = 3;
}

message TokenResponse {
  string token = 1;
}

message ResetRequest {
}

message Service {
  string id = 1;
  string name = 2;
  string mode = 3;

  message Container {
    string machine_id = 1;
    // JSON encoded Docker types.Container.
    bytes container = 2;
  }

  repeated Container containers = 4;
}

message InspectServiceRequest {
  string id = 1;
}

message InspectServiceResponse {
  Service service = 1;
}
