syntax = "proto3";

package zbiorkom.socket;

enum RouteType {
    Tram = 0;
    Subway = 1;
    Rail = 2;
    Bus = 3;
    Ferry = 4;
    Trolleybus = 11;
}

enum StopTimeType {
    Regular = 0;
    Forbidden = 1;
    OnDemand = 3;
}

enum DepartureStatus {
    Scheduled = 0; // Based on static GTFS data
    Live = 1;      // Real-time prediction available
    Departed = 2;  // Vehicle has already left this stop
    Cancelled = 3; // Trip is cancelled
}

message ClientMessage {
    oneof payload {
        SubscribeMapFeatures subscribe_map_features = 1;
        SubscribeStopDepartures subscribe_stop_departures = 2;
        SubscribeTripUpdate subscribe_trip_update = 3;

        Unsubscribe unsubscribe = 4;
    }
}

message SubscribeMapFeatures {
    string city = 1;
    Bounds bounds = 2;
    float zoom = 3;
    repeated string filter_routes = 4;
    repeated string filter_models = 5;
    optional int32 filter_direction = 6;
}

message SubscribeStopDepartures {
    string city = 1;
    string stop_id = 2;
    
    int32 limit = 3;
    int64 time = 4;
    bool show_arrivals = 5;
    repeated string destinations = 6;
}

message SubscribeTripUpdate {
    string city = 1;
    oneof identifier {
        string trip_id = 2;
        string vehicle_id = 3;
    }
}

message Unsubscribe {}

message ServerMessage {
    oneof payload {
        MapFeaturesUpdate map_features_update = 1;
        StopDeparturesUpdate stop_departures_update = 2;
        TripUpdateData trip_update_data = 3;

        Error error = 99;
    }
}

message Error {
    string code = 1;
    string message = 2;
}

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

message Bounds {
    double min_lon = 1;
    double min_lat = 2;
    double max_lon = 3;
    double max_lat = 4;
}

message Route {
  string id = 1;
  string city = 2;
  string name = 3;
  optional string agency = 4;
  RouteType type = 5;
  string color = 6;
  optional string long_name = 7;
}

message Stop {
    string id = 1;
    string city = 2;
    string name = 3;
    Location location = 4;

    repeated RouteType type = 5;
    repeated Route routes = 6;
    bool station = 7;
    optional int32 bearing = 8;
    optional string direction = 9;
    repeated Exit exits = 10;
}

message Exit {
    string name = 1;
    Location location = 2;
}

message VehicleInfo {
    string id = 1;
    string city = 2;
    Route route = 3;
    string brigade = 4;
    string trip_id = 5;
    Location location = 6;
    float bearing = 7;
    int64 last_ping = 8;
}

message MapFeaturesUpdate {
    bool render_dots = 1;
    repeated VehicleInfo vehicles = 2;
    repeated VehicleDot dots = 3; 
    repeated Stop stops = 4;
}

message VehicleDot {
    string color = 1;
    Location location = 2;
}

message StopDeparturesUpdate {
    string city = 1;
    string stop_id = 2;
    Stop stop_details = 3;
    repeated DepartureEntry departures = 4;
}

message DepartureEntry {
    TripDetails trip = 1;
    DepartureEvent departure = 2;
    optional DepartureEvent destination = 3;
    optional VehicleInfo position = 4; 
}

message TripDetails {
    string id = 1;
    string city = 2;
    string headsign = 3;
    Route route = 4;
    string short_name = 5;
    string brigade = 6;
    string gtfs_id = 7;
    string block = 8;
    int64 start_time = 9;
}

message DepartureEvent {
    string stop_id = 1;
    int64 scheduled = 2;
    int64 predicted = 3;
    optional int32 delay = 4;
    bool cancelled = 5;
    bool estimated = 6;
    string platform = 7;
    string track = 8;
}

message TripUpdateData {
    string city = 1;
    optional TripDetails trip = 2;
    optional string shape = 3; 
    optional VehicleInfo vehicle = 4;
    repeated TripStop stops = 5;
    optional int32 current_stop_index = 6;
    optional int64 last_update = 7;
}

message TripStop {
    Stop stop = 1;
    
    TripTime arrival = 2;
    TripTime departure = 3;
    
    string platform = 4;
    string track = 5;
    repeated string alerts = 6;
    
    int32 sequence = 7;
    StopTimeType type = 8;
}

message TripTime {
    int64 scheduled = 1;
    int64 predicted = 2;
    int32 delay = 3;
    
    DepartureStatus status = 4;
}