syntax = "proto3";

package labgrid;

service Coordinator {
  rpc ClientStream(stream ClientInMessage) returns (stream ClientOutMessage) {}

  rpc ExporterStream(stream ExporterInMessage) returns (stream ExporterOutMessage) {}

  rpc AddPlace(AddPlaceRequest) returns (AddPlaceResponse) {}

  rpc DeletePlace(DeletePlaceRequest) returns (DeletePlaceResponse) {}

  rpc GetPlaces(GetPlacesRequest) returns (GetPlacesResponse) {}

  rpc AddPlaceAlias(AddPlaceAliasRequest) returns (AddPlaceAliasResponse) {}

  rpc DeletePlaceAlias(DeletePlaceAliasRequest) returns (DeletePlaceAliasResponse) {}

  rpc SetPlaceTags(SetPlaceTagsRequest) returns (SetPlaceTagsResponse) {}

  rpc SetPlaceComment(SetPlaceCommentRequest) returns (SetPlaceCommentResponse) {}

  rpc AddPlaceMatch(AddPlaceMatchRequest) returns (AddPlaceMatchResponse) {}

  rpc DeletePlaceMatch(DeletePlaceMatchRequest) returns (DeletePlaceMatchResponse) {}

  rpc AcquirePlace(AcquirePlaceRequest) returns (AcquirePlaceResponse) {}

  rpc ReleasePlace(ReleasePlaceRequest) returns (ReleasePlaceResponse) {}

  rpc AllowPlace(AllowPlaceRequest) returns (AllowPlaceResponse) {}

  rpc CreateReservation(CreateReservationRequest) returns (CreateReservationResponse) {}

  rpc CancelReservation(CancelReservationRequest) returns (CancelReservationResponse) {}

  rpc PollReservation(PollReservationRequest) returns (PollReservationResponse) {}

  rpc GetReservations(GetReservationsRequest) returns (GetReservationsResponse) {}
}

message ClientInMessage {
  oneof kind {
    Sync sync = 1;
    StartupDone startup = 2;
    Subscribe subscribe = 3;
  };
};

message Sync {
  uint64 id = 1;
};

message StartupDone {
  string version = 1;
  string name = 2;
};

message Subscribe {
  optional bool is_unsubscribe = 1;
  oneof kind {
    bool all_places = 2;
    bool all_resources = 3;
  }
};

message ClientOutMessage {
  optional Sync sync = 1;
  repeated UpdateResponse updates = 2;
};

message UpdateResponse {
  oneof kind {
    Resource resource = 1;
    Resource.Path del_resource = 2;
    Place place = 3;
    string del_place = 4;
  };
};

message ExporterInMessage {
  oneof kind {
    Resource resource = 1;
    StartupDone startup = 2;
    ExporterResponse response = 3;
  };
};

message Resource {
  message Path {
    optional string exporter_name = 1;
    string group_name = 2;
    string resource_name = 3;
  }
  Path path = 1;
  string cls = 2;
  map<string, MapValue> params = 3;
  map<string, MapValue> extra = 4;
  string acquired = 5;
  bool avail = 6;
};

message MapValue {
  oneof kind {
    bool bool_value = 1;
    int64 int_value = 2;
    uint64 uint_value = 3;
    double float_value = 4;
    string string_value = 5;
    // FIXME do we need arrays?
  }
};

message ExporterResponse {
  bool success = 1;
  optional string reason = 2;
};

message Hello {
  string version = 1;
}

message ExporterOutMessage {
  oneof kind {
    Hello hello = 1;
    ExporterSetAcquiredRequest set_acquired_request = 2;
  };
};

message ExporterSetAcquiredRequest {
  string group_name = 1;
  string resource_name = 2;
  optional string place_name = 3;
};

message AddPlaceRequest {
  string name = 1;
};

message AddPlaceResponse {
};

message DeletePlaceRequest {
  string name = 1;
};

message DeletePlaceResponse {
};

message GetPlacesRequest {
};

message GetPlacesResponse {
  repeated Place places = 1;
}

message Place {
  string name = 1;
  repeated string aliases = 2;
  string comment = 3;
  map<string, string> tags = 4;
  repeated ResourceMatch matches = 5;
  optional string acquired = 6;
  repeated string acquired_resources = 7;
  repeated string allowed = 8;
  double created = 9;
  double changed = 10;
  optional string reservation = 11;
};

message ResourceMatch {
  string exporter = 1;
  string group = 2;
  string cls = 3;
  optional string name = 4;
  optional string rename = 5;
};

message AddPlaceAliasRequest {
  string placename = 1;
  string alias = 2;
};

message AddPlaceAliasResponse {
};

message DeletePlaceAliasRequest {
  string placename = 1;
  string alias = 2;
};

message DeletePlaceAliasResponse {
};

message SetPlaceTagsRequest {
  string placename = 1;
  map<string, string> tags = 2;
};

message SetPlaceTagsResponse {
};

message SetPlaceCommentRequest {
  string placename = 1;
  string comment = 2;
};

message SetPlaceCommentResponse {
};

message AddPlaceMatchRequest {
  string placename = 1;
  string pattern = 2;
  optional string rename = 3;
};

message AddPlaceMatchResponse {
};

message DeletePlaceMatchRequest {
  string placename = 1;
  string pattern = 2;
  optional string rename = 3;
};

message DeletePlaceMatchResponse {
};

message AcquirePlaceRequest {
  string placename = 1;
};

message AcquirePlaceResponse {
};

message ReleasePlaceRequest {
  string placename = 1;
  optional string fromuser = 2;
};

message ReleasePlaceResponse {
};

message AllowPlaceRequest {
  string placename = 1;
  string user = 2;
};

message AllowPlaceResponse {
};


message CreateReservationRequest {
  map<string, Reservation.Filter> filters = 1;
  double prio = 2;
};

message CreateReservationResponse {
  Reservation reservation = 1;
};

message Reservation {
  message Filter {
    map<string, string> filter = 1;
  }
  string owner = 1;
  string token = 2;
  int32 state = 3;
  double prio  = 4;
  map<string, Filter> filters = 5;
  map<string, string> allocations = 6;
  double created = 7;
  double timeout = 8;
};

message CancelReservationRequest {
  string token = 1;
};

message CancelReservationResponse {
};

message PollReservationRequest {
  string token = 1;
};

message PollReservationResponse {
  Reservation reservation = 1;
};

message GetReservationsResponse {
  repeated Reservation reservations = 1;
};

message GetReservationsRequest {
};
