syntax = "proto3";

package planner;
import "Modes.proto";

option java_multiple_files = true;

message PlanRequest {

  // Origin as a WGS84 "latitude,longitude" pair. Required by the supported coordinate-based planning path.
  optional string fromPlace = 1;

  // Destination as a WGS84 "latitude,longitude" pair. Required by the supported coordinate-based planning path.
  optional string toPlace = 2;

  // Reserved location identifier. Not implemented as a supported alternative to fromPlace.
  optional string fromId = 3;

  // Reserved location identifier. Not implemented as a supported alternative to toPlace.
  optional string toId = 4;

  // Reserved via-coordinate pair. Current planning adapters do not apply via routing.
  optional string viaPlace = 5;

  // Reserved via identifier. Not implemented; identifier-based requests may be rejected.
  optional string viaId = 6;

  // Requested departure or arrival instant in ISO 8601 with an offset or Z. Omitted/empty uses now in the default adapter.
  optional string timestamp = 7;

  // True interprets timestamp as an arrival target; otherwise it is a departure target.
  optional bool arriveBy = 8;

  // Reserved preference. Currently not consumed by backend request expansion or routing policy; setting it does not suppress alternatives.
  optional bool publicTransportOnly = 9;

  // Excludes ordinary first-mile alternative candidates. Explicit flex candidates are appended separately when useFlexibleRouting is true.
  repeated model.enumerations.NonTransitMode excludedFirstMileModes = 10;

  // Excludes ordinary last-mile alternative candidates. Explicit flex candidates are appended separately when useFlexibleRouting is true.
  repeated model.enumerations.NonTransitMode excludedLastMileModes = 11;

  // Additional transfer time in seconds for the default adapter. Compatibility adapters may have different transfer-time semantics.
  optional int32 transferSlack = 12;

  // Adapter-dependent surcharge inclusion preference. False is not enforced as a universal filter by the default adapter.
  optional bool includeWithSurcharges = 13;

  // Adapter-dependent on-demand inclusion preference. Distinct from useFlexibleRouting; not a universal exclusion of flex legs.
  optional bool includeOnDemandTransit = 14;

  // Transit modes to exclude. Available modes and exclusion support depend on the configured adapter and source coverage.
  repeated model.enumerations.TransitMode excludeModes = 16;

  // If true, relaxes the default minimum visible result grade of 4.0. Feasibility, candidate matching and result limits still apply.
  optional bool allowWorseOptions = 17;

  // Excludes ordinary direct-mode alternative candidates. Does not remove a walk-only base result or separately enabled flex candidates.
  repeated model.enumerations.NonTransitMode excludedUnimodalModes = 18;

  // Optional speed preferences; omitted walking/cycling speeds use 5/18 km/h respectively.
  optional UserPreferences userPreferences = 19;

  // Adds WATER, BUS, TRAM, RAIL and METRO exclusions. Does not exclude every transit enum or skip the base planning request.
  optional bool disablePublicTransport = 20;

  // Minutes subtracted from departure requests or added to arrival requests in the default adapter. Omitted uses 5; explicit zero disables adjustment. Negative values reverse the shift. Direct non-transit candidates use zero slack.
  optional int32 timeSlack = 21;

  // Adds explicit flexible access/egress and direct-flex candidates where supported. Does not replace the normal base request. Omitted/false disables explicit flex expansion, not necessarily every on-demand service in source data.
  optional bool useFlexibleRouting = 22;

  // Booking-time controls for explicit flex candidates.
  optional FlexOptions flexOptions = 23;

  // Requests optional pricing enrichment for transit/flex journeys. Defaults to false. Missing tariff data can yield unknown prices or absent enrichment.
  optional bool includePricing = 24;

  // Fare options used with includePricing: train class and age-based flex tariff selection.
  optional PricingOptions pricingOptions = 25;

  // Increases non-flex walking reluctance in the default adapter. A preference, not a maximum walking distance or accessibility guarantee.
  optional bool lessWalking = 26;

  // Opaque hash returned by a transit/flex trip. Replays one matching candidate and filters to exact matching itineraries. No match yields an empty result; malformed input can fail. Not a persistent subscription.
  optional string itineraryHash = 27;

  // Includes town in compatible stop names by default. Explicit false separates the town into Quay.town where supported.
  optional bool includeTownInStopName = 28;
}

message FlexOptions {

  // Omits booking-time input for explicit flex planning. Does not change operator booking rules. Cannot be combined with a nonempty bookingTime.
  optional bool disableBookingWindow = 1;

  // Time at which booking is being considered, in ISO 8601. Defaults to now plus five minutes. Use an explicit offset or Z; timezone-less acceptance is source-dependent.
  optional string bookingTime = 2;
}

enum UserSpeed {

  // 4 km/h walking; 14 km/h cycling.
  SLOW = 0;

  // 5 km/h walking; 18 km/h cycling.
  AVERAGE = 1;

  // 6 km/h walking; 22 km/h cycling.
  FAST = 2;
}

message UserPreferences {

  // Walking speed enum: SLOW=4, AVERAGE=5, FAST=6 km/h. Omitted uses 5 km/h.
  optional UserSpeed walkingSpeed = 1;

  // Cycling speed enum: SLOW=14, AVERAGE=18, FAST=22 km/h. Omitted uses 18 km/h.
  optional UserSpeed bikingSpeed = 2;

  // Adds 5 km/h only when bikingSpeed is explicitly present. If bikingSpeed is absent, the default remains 18 km/h.
  optional bool hasEbike = 3;
}

message PricingOptions {

  // Age >= 65 selects the senior flex tariff where configured. General child/senior discounts for ordinary transit are not applied. Omitted age has scalar default zero.
  int32 age = 1;

  // Selects first/second-class rail fare tables. Defaults to SECOND_CLASS; affects pricing, not journey selection.
  TravelClass travel_class = 2;
}

enum TravelClass {
  SECOND_CLASS = 0;
  FIRST_CLASS = 1;
}
