// Copyright 2024 MOIA GmbH

syntax = "proto3";

// This schema is not intended to be used directly.
// This is an internal schema that represents an agreed structure of the next version of the public API.
// It will be merged into `public/moia/fleet/state` once the implementation is ready.
package moia.fleet.state.v1beta6;

import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "moia/type/v1/latlon.proto";
import "moia/type/v1/latlon_with_heading.proto";
import "moia/type/v1/time_interval.proto";

option go_package = "./fleetstatev1beta6";
option java_multiple_files = false;
option java_outer_classname = "FleetStateServiceV1Beta6";
option java_package = "io.moia.protos.fleet.state.v1beta6";

/**
 * FleetStateService provides access and management capabilities for fleets and their vehicles.
 * It allows API users to retrieve information about their fleets, including details about the vehicles within those fleets and their current state.
 * Furthermore, it allows issuing updates and commands to the vehicles, such as updating the mission, and operational commands.
 */
service FleetStateService {
  /**
   *  List all the fleets that an API user has access to.
   *
   * Potential Errors:
   *
   * - INVALID_ARGUMENT: if the incoming request failed to validate against the buf annotations
   *
   * - NOT_FOUND: if a page token was not found, provides ErrorInfo in error details
   *
   * - INTERNAL: internal error occurred
   */
  rpc ListFleets(ListFleetsRequest) returns (ListFleetsResponse) {}

  /**
   * Get a particular fleet by id.
   *
   * Potential Errors:
   *
   * - INVALID_ARGUMENT: if the incoming request failed to validate against the buf annotations
   *
   * - NOT_FOUND: if the requested fleet was not found, provides ResourceInfo in details
   *
   * - INTERNAL: internal error occurred
   */
  rpc GetFleet(GetFleetRequest) returns (GetFleetResponse) {}

  /**
   * List all vehicles which are contained in a fleet.
   *
   * Potential Errors:
   *
   * - INVALID_ARGUMENT: if the incoming request failed to validate against the buf annotations
   *
   * - NOT_FOUND: if the page token was not found, provides ErrorInfo in error details
   *
   * - INTERNAL: internal error occurred
   */
  rpc ListVehicles(ListVehiclesRequest) returns (ListVehiclesResponse) {}

  /**
   * Get a particular vehicle by id.
   *
   * Potential Errors:
   *
   * - INVALID_ARGUMENT: if the incoming request failed to validate against the buf annotations
   *
   * - NOT_FOUND: if the requested vehicle was not found, provides ResourceInfo in details
   *
   * - INTERNAL: internal error occurred
   */
  rpc GetVehicle(GetVehicleRequest) returns (GetVehicleResponse) {}

  /**
   * Stream the vehicle's movement telemetry.
   *
   * Potential Errors:
   *
   * - INVALID_ARGUMENT: if the incoming request failed to validate against the buf annotations
   *
   * - NOT_FOUND: if the requested vehicle was not found, provides ResourceInfo in details
   *
   * - INTERNAL: internal error occurred
   */
  rpc SubscribeToVehicleTelemetryMovement(SubscribeToVehicleTelemetryMovementRequest) returns (stream SubscribeToVehicleTelemetryMovementResponse) {}

  /**
   * Update the waypoints of a vehicle mission
   *
   * Fails with INVALID_ARGUMENT with the following reasons:
   * - MISSION_UPDATE_ROUTE_VALIDATION_ERROR - Mission update could not be done because of route validation error
   * - MISSION_UPDATE_BAD_REQUEST - Mission update could not be done because of a bad request error
   * - FLEET - Client is not configured to have access to any fleets
   * - MISSION_UPDATE_MISSING_PASSENGER_INFO - Mission update could not be done because of missing passenger details for a ride
   *
   * Fails with FAILED_PRECONDITION with the following reasons:
   * - MISSION_ID_IS_OUTDATED - A concurrency conflict occurred between updates
   *
   * Fails with NOT_FOUND for the following resource types:
   * - VEHICLE - Vehicle not found
   * - FLEET - Fleet not found
   *
   * Fails with INTERNAL with the following reasons:
   * - INTERNAL_ERROR - an unexpected internal error occurred
   *
   * Fails with DEADLINE_EXCEEDED with the following reasons:
   * - UPDATE_DEADLINE_EXCEEDED - Mission update could not be applied in time. Rollback was successful
   * - NO_VEHICLE_ACK - Vehicle did not acknowledge the mission update in time. Rollback was successful
   *
   * Fails with UNAVAILABLE with the following reasons:
   * - RETRIABLE_UPDATE_DEADLINE_EXCEEDED - Mission update could not be applied in time, but it is advisable to retry. Rollback was successful
   */
  rpc UpdateVehicleMission(UpdateVehicleMissionRequest) returns (UpdateVehicleMissionResponse) {}

  /**
   * Stream events related to missions of vehicles in a fleet.
   *
   * Potential Errors:
   *
   * - INVALID_ARGUMENT: if the incoming request failed to validate against the buf annotations
   *
   * - INTERNAL: internal error occurred
   */
  rpc SubscribeToFleetMissionEvents(SubscribeToFleetMissionEventsRequest) returns (stream SubscribeToFleetMissionEventsResponse) {}

  /**
   * Poll events related to missions of vehicles in a fleet
   *
   * Potential Errors:
   *
   * - INVALID_ARGUMENT: if the incoming request failed to validate against the buf annotations
   *
   * - INTERNAL: internal error occurred
   */
  rpc PollFleetMissionEvents(PollFleetMissionEventsRequest) returns (PollFleetMissionEventsResponse) {}

  /**
   * SendBoardingPreparationSuccessful will signal the vehicle that the passenger is ready to board.
   * This is overriding authentication mechanisms on the vehicle and signals that the authentication for a particular ride can be considered successful.
   * As a result of this the door of the vehicle opens if it is not already open.
   *
   * Potential Errors:
   *
   * - INVALID_ARGUMENT: if the incoming request failed to validate against the buf annotations
   *
   * - NOT_FOUND: if the requested vehicle was not found, provides ResourceInfo in details
   *
   * - INTERNAL: internal error occurred
   */
  rpc SendBoardingPreparationSuccessful(SendBoardingPreparationSuccessfulRequest) returns (SendBoardingPreparationSuccessfulResponse) {}

  /**
   * Get capacity definition for a particular vehicle group.
   *
   * Potential Errors:
   *
   * - INVALID_ARGUMENT: if the incoming request failed to validate against the buf annotations
   *
   * - NOT_FOUND: if the requested vehicle group was not found, provides ResourceInfo in details
   *
   * - INTERNAL: internal error occurred
   */
  rpc GetCapacityDefinition(GetCapacityDefinitionRequest) returns (GetCapacityDefinitionResponse) {}

  /**
   * SendStartRide will signal the vehicle that the passenger confirms they are ready for the vehicle to depart.
   *
   * Potential Errors:
   *
   * - INVALID_ARGUMENT: if the incoming request failed to validate against the buf annotations
   *
   * - NOT_FOUND: if the requested vehicle was not found, provides ResourceInfo in details
   *
   * - INTERNAL: internal error occurred
   */
  rpc SendStartRideCommand(SendStartRideCommandRequest) returns (SendStartRideCommandResponse) {}
}

// Request to SendBoardingPreparationSuccessful.
message SendBoardingPreparationSuccessfulRequest {
  // The Id of the vehicle to start the boarding preparation for.
  string vehicle_id = 1;
  // The ride Id associated with the boarding process.
  string ride_id = 2;
  // The Id of the fleet the vehicle belongs to.
  string fleet_id = 3;
}

// The response to SendBoardingPreparationSuccessful. Empty response indicating that command was perceived.
message SendBoardingPreparationSuccessfulResponse {}

// Request to SendStartRide.
message SendStartRideCommandRequest {
  // The Id of the request that initiated the "start-ride" process.
  // This should be taken from the WaitingForStartRideCommand event.
  string request_id = 1;
  // The Id of the vehicle for which the signal is issued.
  string vehicle_id = 2;
  // The Id of the fleet the vehicle belongs to.
  string fleet_id = 3;
}

// The response to SendStartRide. Empty response indicates that the command was received.
message SendStartRideCommandResponse {}

// Retrieve the capacity definition for a vehicle group.
message GetCapacityDefinitionRequest {
  // Id of the requested capacity definition.
  // This is the same id that is used in `Vehicle.Capacity.capacity_definition_id`.
  string capacity_definition_id = 1;
}

// The response containing the capacity definition for a vehicle group.
message GetCapacityDefinitionResponse {
  // The capacity definition for the vehicle group.
  CapacityDefinition capacity_definition = 1;
}

/**
 * Stream the events of missions of vehicles in the fleet.
 * If `last_message_id` is omitted only new events will be streamed.
 * It is very important that you omit `last_message_id` only for the first call to StreamVehicleMissionEvents.
 * Later `last_message_id` should be set to the `message_id` of the last received item,
 * otherwise you could miss all the entries that are added in between.
 */
message SubscribeToFleetMissionEventsRequest {
  // The Id of fleet for which mission events should be streamed
  string fleet_id = 1;
  // The Id of the last message received in the stream, use this to continue reading the stream from the last received message.
  optional string last_message_id = 2;
}

/**
 * If no `last_message_id` was provided in the StreamVehicleMissionEventsRequest
 * the stream will immediately send out a response after being established with an empty event and the Id of the last message in the stream.
 * In all other cases both an event and a `message_id` will be provided.
 */
message SubscribeToFleetMissionEventsResponse {
  // New incoming Mission Event. Event is empty on initial subscribe.
  optional MissionEvent event = 1;
  // The Id of this message, use this as `last_message_id` when reconnecting to continue reading.
  string message_id = 2;
}

/**
 * Request to poll mission events for a fleet with given Id.
 * If `last_message_id` is provided, all events since then are requested for the fleet with given Id.
 * If `last_message_id` is omitted, the request polls any mission events occurring during the request deadline.
 */
message PollFleetMissionEventsRequest {
  // Id of fleet for which mission events should be polled
  string fleet_id = 1;
  // The Id of the last message received in the poll, use this to read the events from the last received message.
  optional string last_message_id = 2;
}

/**
 * If no `last_message_id` was provided in the PollFleetMissionEventsRequest, the `message_id` of the last message in the stream will be returned.
 * This can be used to continue reading the stream from the last received message.
 */
message PollFleetMissionEventsResponse {
  // List of Mission Events which were received since last poll.
  repeated MissionEvent events = 1;
  // The Id of this message, use this as `last_message_id` in the next request to continue reading.
  optional string message_id = 2;
}

// The request to update a Vehicle's Mission to the given new Mission.
message UpdateVehicleMissionRequest {
  // The Id of the vehicle to update the mission for.
  string vehicle_id = 1;
  // The waypoints for the new mission.
  // There can be at most 50 waypoints per mission update.
  repeated Waypoint waypoints = 2;
  /**
   * The Id of the previous mission. This is used to ensure that the mission is only updated if the previous mission is still the current mission.
   * If this vehicle has never received a mission, this can be left empty.
   */
  optional string previous_mission_id = 3;
  // The Id of the fleet the vehicle belongs to.
  string fleet_id = 4;
  // The passenger groups for the updated mission.
  repeated Vehicle.Mission.RidePassengerGroup passengers_groups = 5;

  /**
   * A Waypoint is a particular stopping place that a Vehicle is requested to go to.
   * Waypoints consists of both a location and Waypoint Actions that are requested to occur at the Waypoint.
   * Note that there can be at most 50 waypoints per mission update.
   */
  message Waypoint {
    // Waypoint Action represents an activity that is required at a specific Waypoint.
    message Action {
      // Type of Waypoint Action
      oneof action_type {
        // Action to pick up a passenger
        Vehicle.Mission.Waypoint.Action.Pickup pickup = 1;
        // Action to drop off a passenger
        Vehicle.Mission.Waypoint.Action.Dropoff dropoff = 2;
        // Action to send vehicle for rebalancing inside the Operating Area.
        Vehicle.Mission.Waypoint.Action.Rebalancing rebalancing = 3;
      }
    }

    // The actions performed at the waypoint.
    repeated Action actions = 1;
    // The location of the waypoint.
    NamedLocation location = 2;
  }
}

// The response containing the updated Vehicle's mission.
message UpdateVehicleMissionResponse {
  // The updated mission of the Vehicle.
  Vehicle.Mission new_vehicle_mission = 1;
}

// The request to list Fleets.
message ListFleetsRequest {
  // The maximum size of the response list. If the page_size is unset, the API chooses a default.
  optional int32 page_size = 1;
  // The next_page_token returned by a previous ListFleets operation to advance to the next page of results. If page_token is unset, the first page of results is returned.
  optional string page_token = 2;
}

// Contains a list of fleets accessible to the API user, along with a token for pagination.
message ListFleetsResponse {
  // List of fleets.
  repeated Fleet fleets = 1;
  // The next_page_token can be used to retrieve the next page of results in a subsequent ListFleets call. An unset next_page_token indicates that the result represents the last page.
  optional string next_page_token = 2;
}

// The request to get a Fleet by Id.
message GetFleetRequest {
  // The Id of the fleet to retrieve.
  string fleet_id = 1;
}

// The response containing the requested Fleet.
message GetFleetResponse {
  // Fleet with requested Id.
  Fleet fleet = 1;
}

// The request to list Vehicles of a specific Fleet.
message ListVehiclesRequest {
  // The Id of the fleet to retrieve.
  string fleet_id = 1;
  // The maximum size of the response list. If the page_size is unset, the API chooses a default.
  optional int32 page_size = 2;
  // The next_page_token returned by a previous ListVehicles operation to advance to the next page of results. If page_token is unset, the first page of results is returned.
  optional string page_token = 3;
}

// Contains a list of vehicles accessible to the API user, along with a token for pagination.
message ListVehiclesResponse {
  // List of Vehicles.
  repeated Vehicle vehicles = 1;
  // The next_page_token can be used to retrieve the next page of results in a subsequent ListVehicles call. An unset next_page_token indicates that the result represents the last page.
  optional string next_page_token = 2;
}

// The request to get a Vehicle by Id.
message GetVehicleRequest {
  // The Id of the vehicle to retrieve.
  string vehicle_id = 1;
  // The Id of the fleet the vehicle belongs to.
  string fleet_id = 2;
}

// Response containing requested Vehicle.
message GetVehicleResponse {
  // Requested Vehicle.
  Vehicle vehicle = 1;
}

/**
 * Stream the vehicle movement.
 */
message SubscribeToVehicleTelemetryMovementRequest {
  // The Id of the vehicle to retrieve.
  string vehicle_id = 1;
  // The Id of the fleet the vehicle belongs to.
  string fleet_id = 2;
}

/**
 * Stream the vehicle movement.
 */
message SubscribeToVehicleTelemetryMovementResponse {
  // Updated movement of Vehicle
  Vehicle.Telemetry.Movement vehicle_movement = 1;
}

/**
 * Returns the vehicle movement as a stream. Only sends updates if the vehicle is online.
 */
// A Fleet is a group of vehicles associated with an Operating Area.
message Fleet {
  // Id of Fleet.
  string id = 1;
  // Description of Fleet.
  string description = 2;
  // The Id of the Operating Area the Fleet belongs to.
  string operating_area_id = 3;
}

// A Vehicle is a single entity of a Fleet, which is expected to move within the operating area completing its current Mission.
message Vehicle {
  // Id of Vehicle.
  string id = 1;
  // The Vehicle Identification Number of this vehicle.
  string vin = 2;
  // License plate of Vehicle.
  string license_plate = 3;
  // A label which is visible on the outside of the vehicle to help the rider to identify the correct vehicle.
  string label = 4;
  // The last known location of the vehicle.
  Telemetry telemetry = 5;
  // Information regarding the type of the vehicle.
  Configuration configuration = 6;
  /**
   * The mission contains the current waypoints assigned to this vehicle.
   * Each waypoint contains a list of actions to perform at the waypoint location.
   */
  Mission mission = 7;
  // The current status of the Vehicle.
  Status status = 8;
  // Vehicle capacity
  Capacity capacity = 9;
  // Planned routes for the current mission of the vehicle.
  RoutePlan route_plan = 10;

  /**
   * A Mission is defined as a set of Waypoints for a specific Vehicle to complete in a predefined order.
   * Each Waypoint has context data (e.g. timestamps / location) and one or more Waypoint Actions (e.g. passenger pickup).
   * Missions can contain anything from zero to tens of ordered Waypoints.
   */
  message Mission {
    // The Id used for versioning of Mission
    string id = 1;
    // The ordered list of waypoints which the vehicle approaches one after another.
    repeated Waypoint waypoints = 2;

    /**
     * A Waypoint is a particular stopping place that a Vehicle is requested to go to.
     * Waypoints consists of both a location and Waypoint Actions that are requested to occur at the Waypoint.
     */
    message Waypoint {
      // The actions performed at the waypoint.
      repeated Action actions = 1;
      // The location of the waypoint.
      NamedLocation location = 2;
      // Id of the waypoint
      string id = 3;

      // Waypoint Action represents an activity that is required at a specific Waypoint.
      message Action {
        // Pick up passengers at the waypoint location.
        message Pickup {
          // Id of the Ride for which pick up is executed.
          string ride_id = 1;
          // The vehicle is requested to arrive at the pick-up location within this time range
          moia.type.v1.TimeInterval promised_arrival_time = 2;
          // The vehicle is requested to only start the passenger boarding process (including passenger authentication) from this time.
          google.protobuf.Timestamp boarding_preparation_allowed_from = 3;
          // The passenger should be eligible to be considered 'No Show' starting from this point in time. If not provided, a default value will be used.
          google.protobuf.Timestamp no_show_allowed_from = 4;
          // The duration that should be reserved for boarding when computing estimated arrival times for the waypoints of this mission.
          // The boarding duration influences the estimated arrival times of later waypoints in the mission.
          // Setting this field is especially useful when boarding durations depend on passengers special needs (boarding a wheelchair, mounting a child seat, storing luggage, etc.).
          // If not provided, a default value will be used.
          google.protobuf.Duration boarding_duration = 5;
          // The expected time when the client expects vehicle boarding to start. This is used when computing estimated arrival times for the waypoints of this mission.
          google.protobuf.Timestamp expected_vehicle_boarding_time = 6;
        }

        // Drop off passengers at the waypoint location.
        message Dropoff {
          // Id of the Ride for which drop off will be executed.
          string ride_id = 1;
          // The vehicle is requested to arrive at the drop-off location within this time range
          moia.type.v1.TimeInterval promised_arrival_time = 2;
          // The duration that should be reserved for deboarding when computing estimated arrival times for the waypoints of this mission.
          // The deboarding duration influences the estimated arrival times of later waypoints in the mission.
          // Setting this field is especially useful when deboarding durations depend on passengers special needs (boarding a wheelchair, mounting a child seat, storing luggage, etc.).
          // If not provided, a default value will be used.
          google.protobuf.Duration deboarding_duration = 3;
        }

        // The vehicle is sent to another destination in the Operating Area e.g. for spatial distribution of the fleet.
        message Rebalancing {
          // A reference id that can be used to track the rebalancing action.
          string reference_id = 1;
          // An optional ordered set of via points that a vehicle should pass through when driving to the Waypoint of a Rebalancing Waypoint Action. Provided to enable testing of SDS/Vehicles along particular routes and not to be used in regular operations.
          // By convention, the intermediate points will not get removed from the mission until the Waypoint itself is completed.
          // Note that there can be at most 100 via points in total per waypoint.
          repeated ViaPoint via_points = 2;
        }

        // The vehicle is not available for regular service e.g. Driver break
        message ServiceBreak {
          // The vehicle is requested to arrive at the break location within this time range
          moia.type.v1.TimeInterval promised_arrival_time = 1;
        }

        // Type of Waypoint Action
        oneof action_type {
          // Pickup Action.
          Pickup pickup = 1;
          // Dropoff Action.
          Dropoff dropoff = 2;
          // Rebalancing Action.
          Rebalancing rebalancing = 3;
          // Service Break Action.
          ServiceBreak service_break = 4;
        }
      }
    }

    /**
     * A RidePassengerGroup describes relevant details for pick-up and drop-off waypoint actions.
     * Each passenger group is connected to a specific ride and contains display names and extra details
     * that should be used by the operator during pick-up and drop-off.
     * There should be an entry for each pick-up/drop-off pair in the mission.
     */
    message RidePassengerGroup {
      // Id of the Ride the passenger group is associated with.
      string ride_id = 1;
      // The name of the main passenger to be displayed on driver app, and operations user interfaces.
      // The first name of the passenger is a good choice for this field.
      // The API client needs to take care to only send personal data that is justified for the use case.
      // The maximum length of this string depends on the vehicle-type, but it typically should not exceed 20 characters. If the actual length is too long it will be truncated before displaying it.
      string display_name = 2;
      // A short identifier (e.g. initials) to be displayed in passenger / driver / operator applications when a display name cannot be used. Should be max 3 UTF-8 characters. If the length is too long it will be truncated before displaying it.
      string short_name = 3;
      // Boarding requirements as used/required for this ride.
      BoardingRequirements boarding_requirements = 4;
      // Impairment details for passengers on this trip.
      Impairments impairments = 5;
      // Flag indicating if an eligibility check should be performed.
      bool eligibility_check = 6;

      /**
       * Requirements checkable for the ride.
       */
      message BoardingRequirements {
        // The number of people expected to board/disembark.
        int32 head_count = 1;
        // Flag indicating whether a child or booster seat is required.
        bool child_seat = 2;
        // Flag indicating whether a passenger with a wheelchair is expected to board/disembark.
        bool wheelchair = 3;
      }

      // Potential impairments that need special consideration during pickup/dropoff.
      message Impairments {
        // Flag indicating whether passenger with a visual impairment is expected.
        bool visual = 1;
      }
    }
  }

  // Configuration contains any information regarding the type of a Vehicle.
  message Configuration {
    // Flag indicating if a vehicle is self driving or not.
    bool self_driving = 1;
  }

  // Status represents a collection of relevant flags for
  message Status {
    // Flag indicating if the vehicle is ready to receive and process new rides.
    bool ready_for_new_rides = 1;
    // Flag indicating if the vehicle is connected and has a recent location.
    bool online = 2;
  }

  // Telemetry contains information about a Vehicle's telemetry data.
  message Telemetry {
    // Movement of a vehicle with coordinates
    Movement movement = 1;

    // Movement represents a Vehicle's movement with coordinates and movement-related attributes.
    message Movement {
      // Location of the movement with heading.
      moia.type.v1.LatLonWithHeading location = 1;
      // Speed in m/s
      optional double speed_meters_per_second = 2;
      // Timestamp of the telemetry (required)
      google.protobuf.Timestamp timestamp = 3;
    }
  }

  // Capacity describes how much passenger occupancy a vehicle can carry.
  // The relationship between different capacity types is defined in the `CapacityDefinition`.
  message Capacity {
    // Id of the related capacity definition.
    string capacity_definition_id = 1;
    // Capacity types of the vehicle, e.g. seat types.
    // There can be maximum 8 capacity types in this list.
    repeated CapacityType types = 2;
    // Convertible capacity types can be converted to different normal capacity types.
    // There can be maximum 4 convertible types in this list.
    repeated CapacityType convertible_types = 3;

    // Type represents a single capacity type of the vehicle, e.g. seat type.
    message CapacityType {
      // Type key matching one of the keys defined in the `CapacityDefinition`.
      string key = 1;
      // Maximum number of this capacity type that can be used in the vehicle.
      int32 count = 2;
    }
  }
}

// A MissionEvent is an event that occurs during the execution of a vehicle mission.
message MissionEvent {
  // Id of the vehicle associated with the mission event.
  string vehicle_id = 1;

  // Timestamp indicating when the mission event occurred.
  google.protobuf.Timestamp timestamp = 2;

  // Type of the new Mission Event.
  oneof type {
    // Event indicating that a passenger was picked up.
    PickedUp picked_up = 3;
    // Event indicating that a passenger was dropped off.
    DroppedOff dropped_off = 4;
    // Event indicating that a passenger didn't show up.
    NotShownUp not_shown_up = 5;
    // Event indicating that the boarding preparation data was updated.
    BoardingPreparationDataUpdated boarding_preparation_data_updated = 6;
    // Event indicating that the boarding preparation has started for a Ride.
    BoardingPreparationStarted boarding_preparation_started = 7;
    // Event indicating that the boarding preparation was completed for a Ride.
    BoardingPreparationCompleted boarding_preparation_completed = 8;
    // Event indicating that a Vehicle has completed a Waypoint.
    WaypointCompleted waypoint_completed = 9;
    // Event indicating that a Vehicle has reached a Waypoint.
    WaypointReached waypoint_reached = 10;
    // Event indicating that the Route of a Vehicle got updated.
    VehicleRouteUpdated route_updated = 11;
    // Event indicating that the service for a Vehicle was cancelled.
    ServiceCancelled service_cancelled = 12;
    // Event indicating that Vehicle is waiting for start ride command.
    WaitingForStartRideCommand waiting_for_start_ride_command = 13;
    // Event indicating that StartRideCommand has been successfully processed.
    StartRideCommandProcessed start_ride_command_processed = 14;
  }

  /**
   * - Prerequisite: Passenger is at the pick-up location and boarding preparation is completed as indicated by a `Boarding Preparation Completed` event.
   * - Cause: Passenger has entered the vehicle and presence is confirmed.
   * - Effect: `Picked Up` action is completed. If all actions at the Waypoint are completed, the Vehicle is ready to drive to next Waypoint with Passenger onboard.
   */
  message PickedUp {
    // Id of the ride associated with the pick-up event.
    string ride_id = 1;
  }

  /**
   * - Prerequisite: Vehicle is at the drop-off location indicated by a `Waypoint Reached` event. The vehicle door is opened.
   * - Cause: Passenger has exited the Vehicle.
   * - Effect: `Dropped Off` action is completed. If all actions at the Waypoint are completed, the Vehicle is ready to drive to next Waypoint.
   */
  message DroppedOff {
    // Id of the ride associated with the drop-off event.
    string ride_id = 1;
  }

  /**
   * - Prerequisite: Vehicle is at the pick-up location indicated by a `Waypoint Reached` event.
   * - Cause: Passenger did not show up at the pick-up location.
   * - Effect: Actions with the same ride_id are discarded. Vehicle leaves without picking up the passenger.
   */
  message NotShownUp {
    // Id of the ride associated with the no-show event.
    string ride_id = 1;
  }

  // The data needed for boarding preparation.
  message BoardingPreparationData {
    // The UUID of the service that the vehicle advertises for Bluetooth Low Energy (BLE) authentication.
    string bluetooth_advertised_service_uuid = 1;
    // The payload which a passenger app hands over to authentication hardware on the vehicle (NFC, BLE).
    string authentication_payload = 2;
    // Numeric pin code for pinpad based authentication. The pin code is a 4-digit number.
    string pin_code = 3;
  }
  /**
   * - Prerequisite: A ride is scheduled for pickup or the boarding preparation data needed to be updated.
   * - Cause: A ride without boarding preparation data is assigned to a vehicle.
   * - Effect: boarding preparation data can be distributed.
   */
  message BoardingPreparationDataUpdated {
    // Id of the ride for which boarding preparation data was updated.
    string ride_id = 1;

    // The boarding preparation data that is potentially used for the boarding preparation process.
    // The actual boarding preparation capabilities of a vehicle are communicated in the BoardingPreparationStarted event.
    BoardingPreparationData authentication_data = 2;
  }

  /**
   * - Prerequisite: Vehicle is at the pick-up location as indicated by a `Waypoint Reached` event.
   * - Cause: Vehicle started the boarding preparation process.
   * - Effect: Vehicle is waiting for boarding preparation to be completed.
   */
  message BoardingPreparationStarted {
    // The authentication capabilities that are known to the system.
    enum BoardingPreparationCapability {
      // Unspecified.
      BOARDING_PREPARATION_CAPABILITY_UNSPECIFIED = 0;
      // Successful boarding preparation signaled via `SendBoardingPreparationSuccessful`.
      BOARDING_PREPARATION_CAPABILITY_API = 1;
      // NFC based boarding preparation.
      BOARDING_PREPARATION_CAPABILITY_NFC = 2;
      // Bluetooth Low Energy based boarding preparation.
      BOARDING_PREPARATION_CAPABILITY_BLE = 3;
      // Pin pad based boarding preparation.
      BOARDING_PREPARATION_CAPABILITY_PINPAD = 4;
    }
    // Id of the ride for which boarding preparation has started.
    string ride_id = 1;

    // The boarding preparation capabilities the underlying vehicle supports.
    repeated BoardingPreparationCapability boarding_preparation_capabilities = 2;

    // The boarding preparation data that is used for the boarding preparation process.
    // Can be used if there is no need to retrieve this upfront via BoardingPreparationDataUpdated.
    BoardingPreparationData authentication_data = 4;
  }

  /**
   * - Prerequisite: Passenger and Vehicle are at the pick-up location indicated by a `Waypoint Reached` event and Boarding Preparation has started indicated by a `Boarding Preparation Started` event.
   * - Cause: Boarding Preparation is completed successfully.
   * - Effect: The door opens.
   */
  message BoardingPreparationCompleted {
    // Id of the ride for which boarding preparation has been completed.
    string ride_id = 1;
  }

  /**
   * - Prerequisite: None
   * - Cause: Vehicle is at Waypoint location.
   * - Effect: Vehicle can start completing the Waypoint Actions.
   */
  message WaypointReached {
    // Id of the waypoint that has been reached.
    string waypoint_id = 1;
  }

  /**
   * - Prerequisite: Vehicle is at the Waypoint location indicated by a `Waypoint Reached` event.
   * - Cause: All Waypoint Actions have been completed or cancelled.
   * - Effect: Vehicle leaves the Waypoint location.
   */
  message WaypointCompleted {
    // Id of the waypoint that has been completed.
    string waypoint_id = 1;
  }

  /**
   * - Prerequisite: Vehicle has completed all Waypoint Actions as indicated by a `Waypoint Completed` event.
   * - Cause: Vehicle route has been updated.
   * - Effect: Following this new route, Vehicle continues to the next Waypoint location.
   */
  message VehicleRouteUpdated {
    // Route of vehicle to the next Waypoint.
    Route route = 1;
  }

  /**
   * - Prerequisite: None.
   * - Cause: Something has happened in a specific vehicle (i.e. vehicle needs maintenance, passenger accident etc.) and operator has decided that vehicle cannot continue fulfilling the mission.
   * - Effect: The mission of the vehicle is cleared of all waypoint actions for rides and corresponding waypoints.
   */
  message ServiceCancelled {
    // The id of any ride affected by the service cancellation.
    repeated string ride_ids = 1;
  }

  /**
   * - Prerequisite: Vehicle supports "start ride" flow and is at a Waypoint with a Pickup Waypoint Action - indicated by a Waypoint Reached event.
   * - Cause: Cabin Safety Check is completed by a Operator.
   * - Effect: Client is notified that the vehicle is waiting for start ride command in order to continue ride.
   */
  message WaitingForStartRideCommand {
    // The correlation id of the start ride flow.
    string request_id = 1;
    // The time when was the event was issued.
    google.protobuf.Timestamp timestamp = 2;
  }

  /**
   * - Prerequisite: Vehicle supports "start ride" flow and is at a Waypoint with a Pickup Waypoint Action.
   * - Cause: A "start ride" command was sent and successfully processed.
   * - Effect: Client is notified that the vehicle has successfully processed "start ride" command.
   */
  message StartRideCommandProcessed {
    // The correlation id of the start ride flow.
    string request_id = 1;
    // The time when was the event was processed.
    google.protobuf.Timestamp timestamp = 2;
    // The source of the start ride command.
    Source source = 3;

    // The source of the start ride command sent.
    enum Source {
      // Unspecified.
      SOURCE_UNSPECIFIED = 0;
      // API call.
      SOURCE_API = 1;
      // In-vehicle button.
      SOURCE_IN_VEHICLE_BUTTON = 2;
    }
  }
}

// The capacity definition describes different capacity types, e.g. seats, supported by the vehicle group.
message CapacityDefinition {
  // Id of capacity definition.
  string id = 1;
  // The capacity types of the vehicle group.
  // There can be maximum 8 capacity types in this list.
  repeated CapacityTypeDefinition types = 2;
  // The convertible capacity types of the vehicle group.
  // There can be maximum 4 convertible types in this list.
  repeated ConvertibleCapacityTypeDefinition convertible_types = 3;

  // Capacity definition for a single capacity type.
  message CapacityTypeDefinition {
    // A human-readable snake_case type key, e.g. "standard_seat", "wheelchair".
    string key = 1;
    // Typical number of this capacity type that can be used in the vehicles of this group.
    // This is just a reference value, actual number of this capacity type in a vehicle can be different.
    int32 count = 2;
    // Defines, how usage this capacity type uses other capacity types.
    // For example, a child seat that needs to be installed on a standard seat would claim one standard seat.
    repeated Claim claims = 3;
    // Key of the convertible type associated with this type, i.e. the capacity type that can be used instead of this type.
    // For example, if a booster seat has "convertible_child_seat" associated with it,
    // it means that convertible child seats can be used as a booster seats.
    optional string associated_convertible = 4;
  }

  // Capacity definition for a convertible capacity type.
  // Convertible capacity types can be converted to different normal capacity types.
  message ConvertibleCapacityTypeDefinition {
    // A human-readable snake_case type key, e.g. "convertible_child_seat".
    string key = 1;
    // Typical number of this capacity type that can be used in the vehicles of this group.
    // This is just a reference value, actual number of this capacity type in a vehicle can be different.
    int32 count = 2;
    // Defines, how usage this capacity type uses other capacity types.
    // For example, a convertible child seat that needs to be installed on a standard seat would claim one standard seat.
    repeated Claim claims = 3;
  }

  // Claim represents how a capacity type blocks another capacity type.
  message Claim {
    // The key of the capacity type that is claimed.
    string key = 1;
    // The number of this capacity type that is claimed.
    int32 count = 2;
  }
}

// VehicleConfiguration contains information about relevant vehicle configuration.
message VehicleConfiguration {
  // Flag indicating if a vehicle is self driving or not.
  bool is_self_driving = 1;
}

// A location that a vehicle can be routed through, but should not stop at.
message ViaPoint {
  // A location that should be passed.
  moia.type.v1.LatLon location = 1;
  // The horizontal direction in degrees, measured clockwise from north (valid range of values: [0 - 360)).
  // The interval is half-closed, 360.0° is invalid, use 0.0° instead.
  optional double heading = 2;
}

// Named location represents a physical location with multi-lingual names.
message NamedLocation {
  // The location of the waypoint.
  moia.type.v1.LatLonWithHeading location = 1;
  // Human-readable labels for the location by language code (ISO 639-1 - two-letter language codes).
  map<string, string> labels = 2;
  // Reference id provided by a Fleet API consumer. This can be used to track the location in the consumer's system.
  optional string reference_id = 3;
}

// Route represents the path a vehicle uses to reach a waypoint together with an estimated arrival time.
message Route {
  // Id of the end waypoint for this route.
  string end_waypoint_id = 1;
  // Estimated travel time for this route only (not including travel times from previous routes).
  // For the first route, this estimation is relative to the current vehicle location.
  google.protobuf.Duration estimated_travel_time = 2;
  // Estimated time of arrival at end waypoint (including this route).
  google.protobuf.Timestamp estimated_time_of_arrival = 3;
  // A polyline that describes the route.
  repeated moia.type.v1.LatLon geometry = 4;
}

// RoutePlan represents the routes for all waypoints of a vehicle's mission and a timestamp indicating when the routes were computed.
message RoutePlan {
  // Timestamp indicating when the routes were computed.
  google.protobuf.Timestamp timestamp = 1;
  // The routes and arrival times for the waypoints of the current mission.
  // Routes are ordered by the waypoint sequence of the mission, i.e. the first route is from the vehicle to the first waypoint,
  // the second route from the first waypoint to the second waypoint, and so on.
  repeated Route routes = 2;
}
