syntax = "proto3";

package satellite.v1;

import "google/protobuf/timestamp.proto";

option csharp_namespace = "Satellite.V1";

service RouteTileDelivery {
  rpc DeliverRouteTiles(DeliverRouteTilesRequest) returns (stream RouteTileEvent);
}

message DeliverRouteTilesRequest {
  RouteSpec route = 1;
  repeated ClientTileRecord client_tiles = 2;
}

message RouteSpec {
  string route_id = 1;
  repeated Waypoint waypoints = 2;
  double region_size_meters = 3;
  int32 zoom = 4;
  repeated GeofencePolygon geofences = 5;
  bool include_geofence_tiles = 6;
}

message Waypoint {
  double lat = 1;
  double lon = 2;
}

message GeofencePolygon {
  repeated Waypoint vertices = 1;
}

message ClientTileRecord {
  int32 z = 1;
  int32 x = 2;
  int32 y = 3;
  double resolution_m_per_px = 4;
  google.protobuf.Timestamp captured_at = 5;
  optional string source = 6;
  bytes content_sha256 = 7;
}

message RouteTileEvent {
  oneof payload {
    RouteManifest manifest = 1;
    TileBatch batch = 2;
    ProgressUpdate progress = 3;
    DeliveryComplete complete = 4;
    DeliveryError error = 5;
  }
}

message RouteManifest {
  uint32 total_candidates = 1;
  uint32 skipped_by_client = 2;
  uint32 to_deliver = 3;
}

message TileBatch {
  uint32 batch_seq = 1;
  repeated TilePayload tiles = 2;
}

message TilePayload {
  int32 z = 1;
  int32 x = 2;
  int32 y = 3;
  double resolution_m_per_px = 4;
  google.protobuf.Timestamp captured_at = 5;
  string source = 6;
  bytes jpeg = 7;
  bytes content_sha256 = 8;
  uint32 route_priority = 9;
}

message ProgressUpdate {
  uint32 delivered = 1;
  uint32 total = 2;
  uint32 downloading = 3;
}

message DeliveryComplete {
  uint32 delivered = 1;
  uint32 skipped_client = 2;
  uint32 skipped_server_filter = 3;
}

message DeliveryError {
  string code = 1;
  string message = 2;
  bool retryable = 3;
}
