// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package maps.fleetengine.v1;

import "google/api/annotations.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/maps/fleetengine/v1/fleetengine.proto";
import "google/maps/fleetengine/v1/header.proto";
import "google/maps/fleetengine/v1/vehicles.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
import "google/type/latlng.proto";
import "google/api/client.proto";

option go_package = "google.golang.org/genproto/googleapis/maps/fleetengine/v1;fleetengine";
option java_multiple_files = true;
option java_outer_classname = "VehicleApi";
option java_package = "google.maps.fleetengine.v1";
option objc_class_prefix = "CFE";

// Vehicle management service.
service VehicleService {
  option (google.api.default_host) = "fleetengine.googleapis.com";

  // CreateVehicle instantiates a new vehicle associated with a rideshare
  // provider in the Fleet Engine. Vehicles must have a unique vehicle ID.
  //
  // The following Vehicle fields are required when creating a Vehicle:
  //
  // * vehicleState
  // * supportedTripTypes
  // * maximumCapacity
  // * vehicleType
  //
  // The following Vehicle fields are ignored when creating a Vehicle:
  //
  // * name
  // * currentTrips
  // * availableCapacity
  // * current_route_segment
  // * current_route_segment_version
  // * waypoint
  // * waypoints_version
  // * remaining_distance_meters
  // * eta_to_next_waypoint
  // * navigation_status
  //
  // All other fields are optional and used if provided.
  rpc CreateVehicle(CreateVehicleRequest) returns (Vehicle) {
    option (google.api.http) = {
      post: "/v1/{parent=providers/*}/vehicles"
      body: "vehicle"
    };
  }

  // GetVehicle returns a vehicle from the Fleet Engine.
  rpc GetVehicle(GetVehicleRequest) returns (Vehicle) {
    option (google.api.http) = {
      get: "/v1/{name=providers/*/vehicles/*}"
    };
  }

  // UpdateVehicle writes updated vehicle data to the Fleet Engine.
  //
  // When updating a Vehicle, the following fields cannot be updated since they
  // are managed by the Fleet Engine:
  //
  // * currentTrips
  // * availableCapacity
  // * current_route_segment_version
  // * waypoints_version
  //
  // The vehicle name also cannot be updated.
  //
  // The waypoints field can be updated, but must contain all the waypoints
  // currently on the vehicle, and no other waypoints.
  rpc UpdateVehicle(UpdateVehicleRequest) returns (Vehicle) {
    option (google.api.http) = {
      put: "/v1/{name=providers/*/vehicles/*}"
      body: "vehicle"
    };
  }

  // UpdateVehicleLocation updates the location of the vehicle.
  // This method is deprecated. Use UpdateVehicle method instead.
  rpc UpdateVehicleLocation(UpdateVehicleLocationRequest) returns (VehicleLocation) {
    option deprecated = true;
    option (google.api.http) = {
      put: "/v1/{name=providers/*/vehicles/*}:updateLocation"
      body: "*"
    };
  }

  // UpdateVehicleAttributes partially updates a vehicle's attributes.
  // Only the attributes mentioned in the request will be updated, other
  // attributes will NOT be altered. Note: this is different in UpdateVehicle,
  // where the whole `attributes` field will be replaced by the one in
  // UpdateVehicleRequest, attributes not in the request would be removed.
  rpc UpdateVehicleAttributes(UpdateVehicleAttributesRequest) returns (UpdateVehicleAttributesResponse) {
    option (google.api.http) = {
      post: "/v1/{name=providers/*/vehicles/*}:updateAttributes"
      body: "*"
    };
  }

  // ListVehicles returns a paginated list of vehicles associated with
  // a provider that match the request options.
  rpc ListVehicles(ListVehiclesRequest) returns (ListVehiclesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=providers/*}/vehicles"
    };
  }

  // SearchVehicles returns a list of vehicles that match the request options.
  rpc SearchVehicles(SearchVehiclesRequest) returns (SearchVehiclesResponse) {
    option (google.api.http) = {
      post: "/v1/{parent=providers/*}/vehicles:search"
      body: "*"
    };
  }

  // SearchFuzzedVehicles returns a list of vehicles that match the request
  // options with their locations fuzzed.
  // Request does not support 'order_by' field.
  // Vehicle matches in response will be in order of distance from pickup point.
  // Vehicle matches in response will only have 'vehicle' and 'trip_type' field
  // set.
  rpc SearchFuzzedVehicles(SearchVehiclesRequest) returns (SearchVehiclesResponse) {
    option (google.api.http) = {
      post: "/v1/{parent=providers/*}/vehicles:searchFuzzed"
      body: "*"
    };
  }
}

// CreateVehicle request message.
message CreateVehicleRequest {
  // The standard Fleet Engine request header.
  RequestHeader header = 1;

  // Required. Must be in the format "providers/{provider}".
  // The provider must be the Project ID (for example, sample-cloud-project)
  // of the Google Cloud Project of which the service account making
  // this call is a member.
  string parent = 3 [(google.api.field_behavior) = REQUIRED];

  // Required. Unique Vehicle ID; must be unique per provider.  The actual
  // format and value is opaque to the Fleet Engine and is determined
  // by the provider.
  string vehicle_id = 4 [(google.api.field_behavior) = REQUIRED];

  // Required. The Vehicle entity to create. When creating a Vehicle, the following
  // fields are required:
  //
  // * vehicle_state
  // * supported_trip_types
  // * maximum_capacity
  // * vehicle_type
  //
  // When creating a Vehicle, the following fields are ignored:
  //
  // * name
  // * current_trips
  // * available_capacity
  // * current_route_segment
  // * current_route_segment_version
  // * waypoints
  // * waypoints_version
  // * remaining_distance_meters
  // * eta_to_next_waypoint
  // * navigation_status
  //
  // All other fields will be used if provided.
  Vehicle vehicle = 5 [(google.api.field_behavior) = REQUIRED];
}

// GetVehicle request message.
message GetVehicleRequest {
  // The standard Fleet Engine request header.
  RequestHeader header = 1;

  // Required. Must be in the format
  // "providers/{provider}/vehicles/{vehicle}".
  // The provider must be the Project ID (for example, sample-cloud-project)
  // of the Google Cloud Project of which the service account making
  // this call is a member.
  string name = 3 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "fleetengine.googleapis.com/Vehicle"
    }
  ];

  // Indicates the minimum timestamp (exclusive) for which
  // vehicle.current_route_segment is retrieved.
  // If route is unchanged since this timestamp, the current_route_segment
  // field is not set in the response. If a minimum is unspecified, the
  // current_route_segment is always retrieved.
  google.protobuf.Timestamp current_route_segment_version = 4;

  // Indicates the minimum timestamp (exclusive) for which vehicle.waypoints
  // data is retrieved. If data is unchanged since this timestamp, the
  // vehicle.waypoints data is not set in the response. If this field is
  // unspecified, vehicle.waypoints is always retrieved.
  google.protobuf.Timestamp waypoints_version = 5;
}

// UpdateVehicle request message.
message UpdateVehicleRequest {
  // The standard Fleet Engine request header.
  RequestHeader header = 1;

  // Required. Must be in the format
  // "providers/{provider}/vehicles/{vehicle}".
  // The {provider} must be the Project ID (for example, sample-cloud-project)
  // of the Google Cloud Project of which the service account making
  // this call is a member.
  //
  // Note that if the name is also specified in the name field of the
  // vehicle and name is set in the update_mask, both names must be the
  // same.  Otherwise it is an Error.
  string name = 3 [(google.api.field_behavior) = REQUIRED];

  // Required. The Vehicle entity update to apply.  When updating a Vehicle,
  // the following fields may not be updated as they are managed by the
  // Fleet Engine.
  //   current_trips
  //   available_capacity
  //   current_route_segment_version
  //   waypoints_version
  // Furthermore, the name of the vehicle cannot be updated.
  Vehicle vehicle = 4 [(google.api.field_behavior) = REQUIRED];

  // Required. A field mask indicating which fields of the Vehicle to update.
  // The update_mask must contain at least one field.
  google.protobuf.FieldMask update_mask = 5 [(google.api.field_behavior) = REQUIRED];
}

// UpdateVehicleLocation request message.
message UpdateVehicleLocationRequest {
  option deprecated = true;

  // The standard Fleet Engine request header.
  RequestHeader header = 1;

  // Required. Must be in the format
  // "providers/{provider}/vehicles/{vehicle}.
  // The {provider} must be the Project ID (for example, sample-cloud-project)
  // of the Google Cloud Project of which the service account making
  // this call is a member.
  string name = 3 [(google.api.field_behavior) = REQUIRED];

  // Required. The location to update to.  The last_location and update_time
  // subfields are required.
  VehicleLocation current_location = 4 [(google.api.field_behavior) = REQUIRED];

  // Set current vehicle state to either ONLINE or OFFLINE;
  // if set to UNKNOWN_VEHICLE_STATE, vehicle state will not be altered.
  VehicleState current_state = 5;
}

// UpdateVehicleAttributes request message.
message UpdateVehicleAttributesRequest {
  // The standard Fleet Engine request header.
  RequestHeader header = 1;

  // Required. Must be in the format
  // "providers/{provider}/vehicles/{vehicle}.
  // The provider must be the Project ID (for example, sample-cloud-project)
  // of the Google Cloud Project of which the service account making
  // this call is a member.
  string name = 3 [(google.api.field_behavior) = REQUIRED];

  // Required. The attributes to update;
  // unmentioned attributes will not be altered or removed.
  // At most 20 attributes; the combined "key:value" string length cannot
  // exceed 256.
  repeated VehicleAttribute attributes = 4 [(google.api.field_behavior) = REQUIRED];
}

// UpdateVehicleAttributes response message.
message UpdateVehicleAttributesResponse {
  // Required. The updated full list of vehicle attributes, including new,
  // altered and untouched attributes.
  repeated VehicleAttribute attributes = 1 [(google.api.field_behavior) = REQUIRED];
}

// SearchVehicles request message.
message SearchVehiclesRequest {
  // Specifies the sort order of the vehicle matches in the response.
  enum VehicleMatchOrder {
    // Default, used for unspecified or unrecognized vehicle matches order.
    UNKNOWN_VEHICLE_MATCH_ORDER = 0;

    // Ascending order by vehicle driving time to the pickup point.
    PICKUP_POINT_ETA = 1;

    // Ascending order by the vehicle driving distance to the pickup point.
    PICKUP_POINT_DISTANCE = 2;

    // Ascending order by vehicle driving time to the dropoff point. This order
    // can only be used if the dropoff_point is specified in the request.
    DROPOFF_POINT_ETA = 3;

    // Ascending order by straightline distance from vehicle location to pickup
    // location. This is used primarily as a backup if the maps backend is not
    // reachable.
    PICKUP_POINT_STRAIGHT_DISTANCE = 4;

    // Ascending order by the match cost.
    COST = 5;
  }

  // The standard Fleet Engine request header.
  RequestHeader header = 1;

  // Required. Must be in the format "providers/{provider}".
  // The provider must be the Project ID (for example, sample-cloud-project)
  // of the Google Cloud Project of which the service account making
  // this call is a member.
  string parent = 3 [(google.api.field_behavior) = REQUIRED];

  // Required. The pickup point to search near.
  TerminalLocation pickup_point = 4 [(google.api.field_behavior) = REQUIRED];

  // The customer's intended dropoff location. The field is required if
  // trip_types contains TripType.SHARED.
  TerminalLocation dropoff_point = 5;

  // Required. Defines the vehicle search radius around the pickup point. Only
  // vehicles within the search radius will be returned. Value must be between
  // 400 and 10000 meters.
  int32 pickup_radius_meters = 6 [(google.api.field_behavior) = REQUIRED];

  // Required. Specifies the maximum number of available vehicles to return. By
  // default, the Fleet Engine limits the number to  50.
  int32 count = 7 [(google.api.field_behavior) = REQUIRED];

  // Required. Specifies the minimum number of passengers allowed in the
  // vehicle. Must number must be greater than or equal to one. The driver is
  // not considered in the capacity search. This number indicates the number of
  // passengers being considered for a trip.
  int32 minimum_capacity = 8 [(google.api.field_behavior) = REQUIRED];

  // Required. Restricts the search to only those vehicles that support at least
  // one of the specified trip types.
  repeated TripType trip_types = 9 [(google.api.field_behavior) = REQUIRED];

  // Restricts the search to only those vehicles that have updated their
  // locations within the specified duration back from now. If this field is not
  // set, the server uses five minutes as the default value.
  google.protobuf.Duration maximum_staleness = 10;

  // Required. Restricts the search to those vehicles with the specified types.
  // At least one vehicle type must be specified.
  repeated Vehicle.VehicleType vehicle_types = 14 [(google.api.field_behavior) = REQUIRED];

  // Callers can form complex logical operations using the
  // requiredAttributes and requiredOneOfAttributes fields.
  //
  // requiredAttributes is a list; requiredOneOfAttributes uses a message which
  // allows a list of lists. In combination, the two fields allow the
  // composition of this expression:
  //
  // ```
  // (required_attribute[0] AND required_attribute[1] AND ...)
  // AND
  // (required_one_of_attribute[0][0] OR required_one_of_attribute[0][1] OR ...)
  // AND
  // (required_one_of_attribute[1][0] OR required_one_of_attribute[1][1] OR ...)
  // ```
  //
  // Restricts the search to only those vehicles with the specified attributes.
  // This field is a conjunction/AND operation. Your app can specify up to 100
  // attributes; however, the combined key:value string length cannot exceed
  // 1024 characters.
  repeated VehicleAttribute required_attributes = 12;

  // Restricts the search to only those vehicles with at least one of
  // the specified attributes applied to each VehicleAttributeList. Within each
  // list, a vehicle must match at least one of the attributes. This field is an
  // inclusive disjunction/OR operation in each VehicleAttributeList and a
  // conjunction/AND operation across the collection of VehicleAttributeList.
  repeated VehicleAttributeList required_one_of_attributes = 15;

  // Restricts the search to only those vehicles with at least one set of the
  // specified attributes in the VehicleAttributeList. Within each list, a
  // vehicle must match all of the attributes. This field is a conjunction/AND
  // operation in each VehicleAttributeList and inclusive disjunction/OR
  // operation across the collection of VehicleAttributeList.
  repeated VehicleAttributeList required_one_of_attribute_sets = 20;

  // Required. Specifies ordering criterion for results.
  VehicleMatchOrder order_by = 13 [(google.api.field_behavior) = REQUIRED];

  // Indicates if a vehicle with an active trip is eligible for
  // another match. If `false`, a vehicle is excluded from search results.
  // If `true`, search results include vehicles with `TripStatus` of
  // `ENROUTE_TO_DROPOFF`. The services only use this field if
  // the `SearchVehicles` request has `TripType` set to EXCLUSIVE.
  // Default value is `false`.
  bool include_back_to_back = 18;

  // Indicates the ID of the trip the searchVehicleRequest is
  // associated with.
  string trip_id = 19;
}

// SearchVehicles response message.
message SearchVehiclesResponse {
  // List of vehicles that match the request options.
  //
  // Ordered by ascending vehicle_pickup_eta, with ties broken by ascending
  // trip_type enum value, followed by matches that don't have
  // vehicle_pickup_eta set.
  //
  // Example response: (Logically represented, not actual response fields):
  //
  // * (VehicleId: Vehicle1, ETA: 10 AM, TripType: SHARED),
  // * (VehicleId: Vehicle2, ETA: 10 AM, TripType: EXCLUSIVE),
  // * (VehicleId: Vehicle3, ETA: 11 AM, TripType: EXCLUSIVE),
  // * (VehicleId: Vehicle4, ETA: Not set, TripType: SHARED),
  // * (VehicleId: Vehicle5, ETA: Not set, TripType: EXCLUSIVE)
  repeated VehicleMatch matches = 1;
}

// ListVehicles request message.
message ListVehiclesRequest {
  // The standard Fleet Engine request header.
  RequestHeader header = 12;

  // Required. Must be in the format "providers/{provider}".
  // The provider must be the Project ID (for example, sample-cloud-project)
  // of the Google Cloud Project of which the service account making
  // this call is a member.
  string parent = 1 [(google.api.field_behavior) = REQUIRED];

  // The maximum number of vehicles to return.
  // Default value: 100.
  int32 page_size = 3;

  // The next_page_token value returned from a previous response, if any.
  string page_token = 4;

  // Specifies the required minimum capacity of the vehicle.
  // The driver is not considered in the capacity search.
  // This is just the number of passengers being considered for a trip.
  // If set, must be greater or equal to 0.
  google.protobuf.Int32Value minimum_capacity = 6;

  // Restrict the search to only those vehicles that support at least
  // one of the specified trip types.
  repeated TripType trip_types = 7;

  // Restrict the search to only those vehicles that have updated
  // their locations within the specified duration back from now.
  // If present, must be a valid positive duration.
  google.protobuf.Duration maximum_staleness = 8;

  // Required. Restrict the search to those vehicles with the specified type categories.
  repeated Vehicle.VehicleType.Category vehicle_type_categories = 9 [(google.api.field_behavior) = REQUIRED];

  // Callers can form complex logical operations using the
  // requiredAttributes and requiredOneOfAttributes fields.
  //
  // requiredAttributes is a list; requiredOneOfAttributes uses a message which
  // allows a list of lists. In combination, the two fields allow the
  // composition of this expression:
  //
  // ```
  // (required_attribute[0] AND required_attribute[1] AND ...)
  // AND
  // (required_one_of_attribute[0][0] OR required_one_of_attribute[0][1] OR ...)
  // AND
  // (required_one_of_attribute[1][0] OR required_one_of_attribute[1][1] OR ...)
  // ```
  //
  // Restrict the search to only those vehicles
  // with the specified attributes. This field is a conjunction/AND operation.
  // Your app can specify up to 100 attributes; however, the combined
  // key:value string length cannot exceed 1024 characters.
  repeated string required_attributes = 10;

  // Restrict the search to only those vehicles with at least one
  // of the specified attributes applied to each VehicleAttributeList.
  // Within each list, a vehicle must match at least one of the attributes.
  // This field is an inclusive disjunction/OR operation in each
  // VehicleAttributeList and a conjunction/AND operation across the collection
  // of VehicleAttributeList.
  // Format: key1:value1|key2:value2|key3:value3...
  repeated string required_one_of_attributes = 13;

  // Restrict the search to only those vehicles with at least one set of the
  // specified attributes in the VehicleAttributeList. Within each list, a
  // vehicle must match all of the attributes. This field is a conjunction/AND
  // operation in each VehicleAttributeList and inclusive disjunction/OR
  // operation across the collection of VehicleAttributeList.
  // Format: key1:value1|key2:value2|key3:value3...
  repeated string required_one_of_attribute_sets = 15;

  // Restrict the search to only those vehicles that have this vehicle state.
  VehicleState vehicle_state = 11;

  // Only return the vehicles with current trip(s).
  bool on_trip_only = 14;
}

// ListVehicles response message.
message ListVehiclesResponse {
  // Depends on vehicles matching request criteria.
  // There will be a maximum number of vehicles returned based on the page_size
  // field in the request.
  repeated Vehicle vehicles = 1;

  // Token to retrieve the next page of vehicles, or empty if there are no
  // more vehicles in the list.
  string next_page_token = 2;

  // Required. Total number of vehicles matching request criteria across all pages.
  int64 total_size = 3 [(google.api.field_behavior) = REQUIRED];
}

// Waypoint describes intermediate points along a route.
message Waypoint {
  // The location of this waypoint.
  google.type.LatLng lat_lng = 1;

  // The estimated time that the vehicle will arrive at this waypoint.
  google.protobuf.Timestamp eta = 2;
}

// VehicleMatch contains the vehicle, ETA, and distance calculations for a
// vehicle that matches the SearchVehiclesRequest.
message VehicleMatch {
  // Type of vehicle match.
  enum VehicleMatchType {
    // Unknown vehicle match type
    UNKNOWN = 0;

    // Exclusive vehicle trip match
    EXCLUSIVE = 1;

    // Back to back ride match.
    BACK_TO_BACK = 2;

    // Carpool ride match.
    CARPOOL = 3;

    // Carpool ride match. The car has an active exclusive trip.
    CARPOOL_BACK_TO_BACK = 4;
  }

  // Required. A vehicle that matches the request.
  Vehicle vehicle = 1 [(google.api.field_behavior) = REQUIRED];

  // The vehicle's driving ETA to the pickup point specified in the
  // request. An empty value indicates a failure in calculating ETA for the
  // vehicle.
  google.protobuf.Timestamp vehicle_pickup_eta = 2;

  // The vehicle's driving distance to the pickup point specified in
  // the request, including any intermediate pickup or dropoff points for
  // an existing ride.  An empty value indicates a failure in calculating
  // distance for the vehicle.
  google.protobuf.Int32Value vehicle_pickup_distance_meters = 3;

  // Required. The straight-line distance between the vehicle and the pickup
  // point specified in the request, including intermediate waypoints for
  // existing trips.
  google.protobuf.Int32Value vehicle_pickup_straight_line_distance_meters = 11 [(google.api.field_behavior) = REQUIRED];

  // The complete vehicle's driving ETA to the drop off point
  // specified in the request. The ETA includes any required visits for active
  // trips that must be completed before the vehicle visits the dropoff_point
  // specified in the request. The value will only be populated when a
  // dropoff_point is specified in the request. An empty value indicates
  // a failure in calculating the ETA for the vehicle to reach
  // the dropoff_point.
  google.protobuf.Timestamp vehicle_dropoff_eta = 4;

  // The vehicle's driving distance (in meters) from the pickup point
  // to the drop off point specified in the request. The distance is only
  // between the two points and does not include the vehicle location or any
  // other points that must be visited before the vehicle visits either the
  // pickup point or dropoff point. The value will only be populated when a
  // dropoff_point is specified in the request. An empty value indicates
  // a failure in calculating the distance from the pickup to
  // dropoff points specified in the request.
  google.protobuf.Int32Value vehicle_pickup_to_dropoff_distance_meters = 5;

  // Required. The trip type of the request that was used to calculate the ETA
  // to the pickup point.
  TripType trip_type = 6 [(google.api.field_behavior) = REQUIRED];

  // The ordered list of waypoints used to calculate the ETA. The list
  // will include the vehicle location, the pickup/drop off points of active
  // trips for the vehicle and the pickup/dropoff points provided in the
  // request. An empty list indicates a failure in calculating ETA for the
  // vehicle.
  repeated Waypoint vehicle_trips_waypoints = 7;

  // Type of the vehicle match.
  VehicleMatchType vehicle_match_type = 8;

  // The method the caller requested for sorting vehicle matches.
  SearchVehiclesRequest.VehicleMatchOrder requested_ordered_by = 9;

  // The actual method that is used to order this vehicle. In normal cases this
  // will match the 'order_by' field from the request, however in certain
  // circumstances such as a failure of google maps backends, a different method
  // may be used (such as PICKUP_POINT_STRAIGHT_DISTANCE).
  SearchVehiclesRequest.VehicleMatchOrder ordered_by = 10;
}

// This messages allows a list-of-list datatype for VehicleAttribute.
message VehicleAttributeList {
  // A list of attributes in this collection.
  repeated VehicleAttribute attributes = 1;
}
