# NOTE: Do not upgrade past Swagger 2. zclient does not support OpenAPI 3 unless
# https://github.com/Yelp/bravado/issues/306 is resolved.
swagger: "2.0"
info:
  description: "API for robot to send vitals up to dispatch."
  version: "1.0.0"
  title: "robot_gateway_api"
  contact:
    name: "Infra"
    email: "infrateam@zoox.com"
    url: "https://git.zooxlabs.com/zooxco/driving"
basePath: "/v1/"
paths:
  /robots/{robotId}/vitals:
    parameters:
    - $ref: "#/parameters/RobotId"
    put:
      summary: "Update Robot vitals (location, battery, etc)."
      operationId: "updateVitals"
      consumes:
      - "application/json"
      produces:
      - "application/json"
      parameters:
      - in: "body"
        name: "vitals"
        description: "The vitals report from the robot."
        required: true
        schema:
          $ref: "#/definitions/Vitals"
      responses:
        "204":
          description: "Update was accepted."
        "400":
          description: "Invalid input."
          schema:
            $ref: "#/definitions/ErrorInfo"
        "500":
          description: "Internal server error."
          schema:
            $ref: "#/definitions/ErrorInfo"
  /robots/{robotId}/mission:
    parameters:
    - $ref: "#/parameters/RobotId"
    get:
      summary: "Get current mission. (deprecated)"
      operationId: "getMission"
      produces:
      - "application/json"
      responses:
        "200":
          description: "The mission."
          schema:
            $ref: "#/definitions/Mission"
        "404":
          description: "Robot not found."
          schema:
            $ref: "#/definitions/ErrorInfo"
        "500":
          description: "Internal server error."
          schema:
            $ref: "#/definitions/ErrorInfo"
    put:
      summary: "Update mission. (deprecated)"
      operationId: "updateMission"
      consumes:
      - "application/json"
      produces:
      - "application/json"
      parameters:
      - in: "body"
        name: "missionUpdate"
        description: "A robot-originated update for a trip-mission."
        required: true
        schema:
          $ref: "#/definitions/TripUpdate"
      responses:
        "200":
          description: "Mission successfully updated."
          schema:
            $ref: "#/definitions/Mission"
        "400":
          description: "Invalid input."
          schema:
            $ref: "#/definitions/ErrorInfo"
        "404":
          description: "No current mission to update."
          schema:
            $ref: "#/definitions/ErrorInfo"
        "500":
          description: "Internal server error."
          schema:
            $ref: "#/definitions/ErrorInfo"
  /robots/{robotId}/mission-queue:
    parameters:
    - $ref: "#/parameters/RobotId"
    get:
      summary: "Get list of missions queued at the robot"
      operationId: "getMissionQueue"
      produces:
      - "application/json"
      responses:
        "200":
          description: "List of missions that are queued at the robot."
          schema:
            $ref: "#/definitions/MissionList"
        "404":
          description: "Robot with ID is not found."
          schema:
            $ref: "#/definitions/ErrorInfo"
        "500":
          description: "Internal server error."
          schema:
            $ref: "#/definitions/ErrorInfo"
  /robots/{robotId}/missions/:
    parameters:
    - $ref: "#/parameters/RobotId"
    get:
      summary: "Get list of missions assigned to the robot"
      operationId: "getMissions"
      produces:
      - "application/json"
      parameters:
        - $ref: "#/parameters/Limit"
        - $ref: "#/parameters/Offset"
        - in: "query"
          name: "only_active"
          description: "Query parameter to be used to filter only active trips"
          # Changed from "boolean" because codegen uses "1" instead of "true".
          type: "string"
          default: "true"
      responses:
        "200":
          description: "List of missions that are assigned to robot."
          schema:
            $ref: "#/definitions/MissionList"
        "404":
          description: "Robot with ID is not found."
          schema:
            $ref: "#/definitions/ErrorInfo"
        "500":
          description: "Internal server error."
          schema:
            $ref: "#/definitions/ErrorInfo"
    post:
      summary: "Create a mission"
      operationId: "createMission"
      consumes:
      - "application/json"
      produces:
      - "application/json"
      parameters:
      - in: "body"
        name: "mission"
        description: "A robot-originated mission request to be created only if there is no existing mission for the robot"
        required: true
        schema:
          $ref: "#/definitions/SingleStopMission"
      responses:
        "201":
          description: "Mission successfully created."
          schema:
            $ref: "#/definitions/Mission"
        "400":
          description: "Invalid input."
          schema:
            $ref: "#/definitions/ErrorInfo"
        "409":
          description: "A mission already exists for the robot"
          schema:
            $ref: "#/definitions/ErrorInfo"
        "500":
          description: "Internal server error."
          schema:
            $ref: "#/definitions/ErrorInfo"
  /robots/{robotId}/missions/{missionId}:
    parameters:
    - $ref: "#/parameters/RobotId"
    - $ref: "#/parameters/MissionId"
    put:
      summary: "Update mission."
      operationId: "updateMissionById"
      consumes:
      - "application/json"
      produces:
      - "application/json"
      parameters:
      - in: "body"
        name: "missionUpdate"
        description: "A robot-originated update for a trip-mission."
        required: true
        schema:
          $ref: "#/definitions/TripUpdate"
      responses:
        "200":
          description: "Mission successfully updated."
          schema:
            $ref: "#/definitions/Mission"
        "400":
          description: "Invalid input."
          schema:
            $ref: "#/definitions/ErrorInfo"
        "404":
          description: "No current mission to update."
          schema:
            $ref: "#/definitions/ErrorInfo"
        "500":
          description: "Internal server error."
          schema:
            $ref: "#/definitions/ErrorInfo"
  /robots/{robotId}/missionAvailability:
    parameters:
    - $ref: "#/parameters/RobotId"
    put:
      summary: "Update availability. (deprecated)"
      operationId: "updateMissionAvailability"
      consumes:
      - "application/json"
      # Note: Required for codegen (it will throw an exception otherwise).
      produces:
      - "application/json"
      parameters:
      - in: "body"
        name: "missionAvailability"
        description: "Describes whether the robot is available."
        required: true
        schema:
          $ref: "#/definitions/MissionAvailability"
      responses:
        "204":
          description: "Availability successfully updated."
        "400":
          description: "Invalid input."
          schema:
            $ref: "#/definitions/ErrorInfo"
        "404":
          description: "Robot not found."
          schema:
            $ref: "#/definitions/ErrorInfo"
        "500":
          description: "Internal server error."
          schema:
            $ref: "#/definitions/ErrorInfo"
  /robots/{robotId}/mission-availability:
    parameters:
    - $ref: "#/parameters/RobotId"
    put:
      summary: "Update availability."
      operationId: "updateMissionAvailabilityV1"
      consumes:
      - "application/json"
      parameters:
      - in: "body"
        name: "missionAvailability"
        description: "Describes whether the robot is available."
        required: true
        schema:
          $ref: "#/definitions/MissionAvailability"
      responses:
        "204":
          description: "Availability successfully updated."
        "400":
          description: "Invalid input."
          schema:
            $ref: "#/definitions/ErrorInfo"
        "404":
          description: "Robot not found."
          schema:
            $ref: "#/definitions/ErrorInfo"
        "500":
          description: "Internal server error."
          schema:
            $ref: "#/definitions/ErrorInfo"
  /robots/{robotId}/lucky:
    parameters:
    - $ref: "#/parameters/RobotId"
    get:
      summary: "Retrieve the next feeling lucky point"
      operationId: "getFeelingLucky"
      produces:
      - "application/json"
      responses:
        "200":
          description: "Operation was successful"
          schema:
            $ref: "#/definitions/Location"
        "404":
          description: "Robot not found."
          schema:
            $ref: "#/definitions/ErrorInfo"
        "500":
          description: "Some internal server error has occurred so retry it again"
          schema:
            $ref: "#/definitions/ErrorInfo"
  /robots/{robotId}/pairing:
    parameters:
    - $ref: "#/parameters/RobotId"
    put:
      summary: "Update the pairing information for the robot"
      operationId: "updatePairing"
      consumes:
      - "application/json"
      parameters:
      - in: "body"
        name: "pairing"
        description: "Pair information that needs to be updated"
        schema:
          $ref: "#/definitions/Pairing"
        required: true
      responses:
        "200":
          description: "Operation was successful"
          schema:
            $ref: "#/definitions/Pairing"
        "404":
          description: "Robot not found or pair info is not found"
          schema:
            $ref: "#/definitions/ErrorInfo"
        "409":
          description: "If pairing already exists with a different robot"
          schema:
            $ref: "#/definitions/ErrorInfo"
        "500":
          description: "Some internal server error has occurred so retry it again"
          schema:
            $ref: "#/definitions/ErrorInfo"
    get:
      summary: "Get the current pair information for the robot"
      operationId: "getPairing"
      produces:
      - "application/json"
      responses:
        "200":
          description: "Operation was successful"
          schema:
            $ref: "#/definitions/Pairing"
        "404":
          description: "Robot with ID not found or there is no pair info"
          schema:
            $ref: "#/definitions/ErrorInfo"
        "500":
          description: "Some internal server error has occurred so retry it again"
          schema:
            $ref: "#/definitions/ErrorInfo"
    delete:
      summary: "Delete the pair information"
      operationId: "deletePairing"
      produces:
      - "application/json"
      responses:
        "204":
          description: "Operation was successful"
        "404":
          description: "Robot with ID not found"
          schema:
            $ref: "#/definitions/ErrorInfo"
        "500":
          description: "Some internal server error has occurred so retry it again"
          schema:
            $ref: "#/definitions/ErrorInfo"
  /robots/{robotId}/logs:
    parameters:
      - $ref: "#/parameters/RobotId"
    post:
      summary: "Create a log message"
      operationId: "postLogEntries"
      consumes:
        - "application/json"
      produces:
        - "application/json"
      parameters:
        - in: "body"
          name: "logEntries"
          description: "Log messages"
          required: true
          schema:
            $ref: "#/definitions/LogEntryList"
      responses:
        "201":
          description: "Log messages successfully created."
        "400":
          description: "Invalid input."
          schema:
            $ref: "#/definitions/ErrorInfo"
        "500":
          description: "Internal server error."
          schema:
            $ref: "#/definitions/ErrorInfo"
  /robots/{robotId}/telemetry-data:
    parameters:
      - $ref: "#/parameters/RobotId"
    put:
      summary: "Update the telemetry data sent from the vehicle"
      operationId: "updateTelemetryData"
      consumes:
      - "application/json"
      produces:
      - "application/json"
      parameters:
      - in: "body"
        name: "telemetry_data"
        required: true
        description: "Custom telemetry data sent from the vehicle"
        schema:
          $ref: "#/definitions/LowBandwidthTelemetryList"
      responses:
        "204":
          description: "Operation was successful"
        "400":
          description: "Invalid input."
          schema:
            $ref: "#/definitions/ErrorInfo"
        "404":
          description: "Robot ID not found"
          schema:
            $ref: "#/definitions/ErrorInfo"
        "500":
          description: "Some internal server error has occurred so retry it again"
          schema:
            $ref: "#/definitions/ErrorInfo"

definitions:
  Mission:
    type: "object"
    # The current code generator does not apply the discriminator in a usable way.
    # discriminator: missionType
    description: "Describes a mission. Top-level/abstract type for more specific missions."
    properties:
      id:
        description: "Id of the mission."
        type: "string"
        format: "uuid"
        readOnly: true
      missionType:
        description: "Type of the mission."
        type: "string"
    required:
    - missionType
  PrivateTripMission:
    description: "A private trip."
    allOf:
    - $ref: "#/definitions/Mission"
    - type: "object"
      properties:
        etaSeconds:
          description: "The ETA to the next stopping point, e.g. the pickup or drop off point."
          type: "number"
          format: "double"
          readOnly: true
        predefinedMissionId:
          type: "string"
        riderInteraction:
          type: "boolean"
        rider:
          $ref: "#/definitions/Rider"
          readOnly: true
        requestedPickup:
          $ref: "#/definitions/Location"
        requestedDestination:
          $ref: "#/definitions/Location"
        requestedMidpoints:
          description: "Points the user would like the robot to drive through when going from Pickup to Destination"
          type: "array"
          items:
            $ref: "#/definitions/Location"
        status:
          $ref: "#/definitions/TripStatus"
      required:
      - requestedPickup
      - requestedDestination
      - status
  IdleMission:
    description: "Mission where the robot should pull over somewhere and wait for further orders."
    allOf:
    - $ref: "#/definitions/Mission"
    - type: "object"
      properties:
        status:
          type: "string"
          enum:
          - DRIVING_TO_IDLE_SPOT
          - IDLING
      required:
      - status
  SingleStopMission:
    description: "A mission which does not include a pickup"
    allOf:
    - $ref: "#/definitions/Mission"
    - type: "object"
      properties:
        requestedDestination:
          $ref: "#/definitions/Location"
        requestedMidpoints:
          description: "Points the robot should drive through on the way to destination"
          type: "array"
          items:
            $ref: "#/definitions/Location"
        status:
          $ref: "#/definitions/TripStatus"
      required:
      - requestedDestination
      - status
  MissionList:
    type: "object"
    description: "Provides a list resource for missions"
    properties:
      metaData:
        $ref: "#/definitions/ListMetaData"
      items:
        type: "array"
        items:
          # Cause the code generator to use a generic JSON Object here,
          # since Mission only holds properties for the base Mission type.
          # We will need to manually parse the Object properties.
          oneOf:
          - $ref: "#/definitions/Mission"
    required:
    - items
  TripUpdate:
    description: "An update from the Robot on a trip's status and/or current route."
    type: "object"
    properties:
      status:
        $ref: "#/definitions/TripStatus"
      route:
        $ref: "#/definitions/Route"
        # Work around for REX-1656, make it required after fix at dispatch node side
        x-nullable: true
  TripStatus:
    description: "Possible states of a trip Mission. https://confluence.zooxlabs.com/confluence/display/INFRA/Mission+Service"
    type: "string"
    # Comment out this enum due to an issue with cpp-restsdk code generation.
    # enum:
    # - SCHEDULED
    # - DRIVING_TO_PICKUP
    # - FORCING_AT_PICKUP
    # - AT_PICKUP
    # - AUTHENTICATING
    # - AUTHENTICATED
    # - INGRESS_COMPLETED
    # - DRIVING_TO_DROP_OFF
    # - FORCING_AT_DROP_OFF
    # - AT_DROP_OFF
    # - COMPLETED
    # - CANCELLED
  MissionAvailability:
    description: "Signal from Robot whether it can accept missions."
    type: "object"
    properties:
      available:
        type: "boolean"
    required:
    - available
  Vitals:
    type: "object"
    description: "Various Robot information to report."
    properties:
      epochTimeMs:
        description: "Robot time at which these vitals were measured."
        type: "number"
        format: "integer"
      position:
        $ref: "#/definitions/Position"
      velocity:
        $ref: "#/definitions/Velocity"
      batteryPercent:
        description: "Battery level percentage."
        type: "number"
        format: "double"
        minimum: 0
        maximum: 1
      route:
        description: "Current route the Robot is on."
        $ref: "#/definitions/Route"
      driveMode:
        description: "Possible drive states that the robot can be in"
        $ref: "#/definitions/DriveMode"
      nogoState:
        description: "Current state the ai_monitor is in"
        $ref: "#/definitions/NogoState"
      teleopEngaged:
        description: "True if the robot has a teleoperator engaged with it"
        type: "boolean"
      teleopNotifications:
        description: "List of notifications generated by teleops"
        type: "array"
        items:
          $ref: "#/definitions/TeleopNotification"
      zrnMinimumReleaseStatus:
        $ref: "#/definitions/ZrnMinimumReleaseStatus"
    required:
    - epochTimeMs
  Route:
    type: "object"
    description: "A list of points describing a route the robot takes."
    properties:
      points:
        description: "A polyline (precision=6) of the robot's currently planned route."
        type: "string"
        # Work around for REX-1656, make it required after fix at dispatch node side
        x-nullable: true
      pointsPassed:
        description: "How many of the points of the passed route have been passed by the robot."
        type: "number"
        format: "integer"
      costSeconds:
        description: "The total cost to drive the full path."
        type: "number"
        format: "double"
    # Work around for REX-1656, make it required after fix at dispatch node side
    # required:
    # - points
  Velocity:
    type: "object"
    description: "Velocities of an object."
    properties:
      northMetersSecond:
        type: "number"
        format: "double"
      eastMetersSecond:
        type: "number"
        format: "double"
      upMetersSecond:
        type: "number"
        format: "double"
      rollDegreesSecond:
        type: "number"
        format: "double"
      pitchDegreesSecond:
        type: "number"
        format: "double"
      yawDegreesSecond:
        type: "number"
        format: "double"
  Position:
    type: "object"
    description: "The position of an object including it's orientation."
    properties:
      location:
        $ref: "#/definitions/Location"
      orientation:
        $ref: "#/definitions/Orientation"
    required:
    - location
  Orientation:
    type: "object"
    description: "What direction an object is pointing in."
    properties:
      rollDegrees:
        type: "number"
        format: "double"
      pitchDegrees:
        type: "number"
        format: "double"
      yawDegrees:
        type: "number"
        format: "double"
    required:
    - rollDegrees
    - pitchDegrees
    - yawDegrees
  Location:
    type: "object"
    description: "A location as a latitude/longitude/altitude."
    properties:
      latitude:
        type: "number"
        format: "double"
      longitude:
        type: "number"
        format: "double"
      altitudeMeters:
        type: "number"
        format: "double"
      displayDescription:
        type: "string"
        description: "A text description of this Location. Could be an address, '1149 Chess Dr, Foster City, CA` or `Zoox HQ` or `Work`. Fully managed by the client."
      serviceAreaPoiId:
        description: "ZRN service area point of interest id of the location as defined in https://git.zooxlabs.com/zooxco/driving/blob/master/vehicle/zrn/sf_service_area.pbtxt#L183"
        type: "integer"
        format: "int64"
    required:
    - latitude
    - longitude
  LowBandwidthTelemetryData:
    type: "object"
    description: "An object of custom telemetry data"
  LowBandwidthTelemetryList:
    type: "object"
    description: "A list of custom telemetry data objects"
    properties:
      items:
        type: array
        items:
          # Cause the code generator to use a generic JSON Object here,
          # We will need to manually parse the Object properties.
          oneof:
            $ref: "#/definitions/LowBandwidthTelemetryData"
  Pairing:
    type: "object"
    description: "Describes information that can be used to pair a robot"
    properties:
      id:
        description: "ID of the Pairing"
        type: "string"
        format: "uuid"
        readOnly: true
  RiderPairing:
    description: "Resource to represent pairing information related to rider"
    allOf:
    - $ref: "#/definitions/Pairing"
    - type: "object"
      properties:
        email:
          type: "string"
          description: "Email address of the user"
          format: "email"
        ttlSeconds:
          type: "number"
          description: "How soon will this pairing expire"
      required:
      - email
  Rider:
    type: "object"
    description: "Resource representing the rider information"
    properties:
      id:
        type: "string"
        description: "Unique string to be used for identifying the rider"
        readOnly: true
        format: "uuid"
      email:
        type: "string"
        description: "Email address of the rider"
        format: "email"
      firstName:
        type: "string"
        description: "First name of the rider"
      lastName:
        type: "string"
        description: "Last Name of the rider"
      phoneNumber:
        type: "string"
        description: "Phone number of the rider"
      hailMode:
        type: "string"
        description: "Hail mode of the rider"
    required:
    - email
    - firstName
  ListMetaData:
    type: "object"
    description: "Provides the meta data for various list resources"
    properties:
      limit:
        type: "integer"
        description: "Max number of resources provided in the list"
      offset:
        type: "integer"
        description: "Offset from which the resources are fetched"
      orderBy:
        type: "string"
        description: "Resource's property on which resources are sorted"
      direction:
        type: "string"
        description: "Direction of the sorting order"
        enum:
        - "ASCENDING"
        - "DESCENDING"
      totalCount:
        type: "integer"
        description: "Total number of resources available"
    required:
    - limit
    - offset
    - orderBy
    - direction
    - totalCount
  DriveMode:
    description: "Possible drive modes the robot can be in"
    type: "string"
    # Comment out this enum due to an issue with cpp-restsdk code generation.
    # enum:
    #   - "UNKNOWN"
    #   - "FAULT"
    #   - "MANUAL"
    #   - "ACC"
    #   - "AUTONOMOUS"
    #   - "ROVE"
  NogoState:
    description: "Possible states of a robot's ai_monitor"
    type: "string"
    # Comment out this enum due to an issue with cpp-restsdk code generation.
    # enum:
    #   - "GO"
    #   - "NOGO"
    #   - "NOGO_DISENGAGED"
  TeleopNotification:
    description: "A notification from teleop"
    type: "object"
    properties:
      priority:
        $ref: "#/definitions/TeleopPriority"
      category:
        $ref: "#/definitions/TeleopCategory"
  TeleopPriority:
    description: "Level of priority from a teleop notification"
    type: "string"
    # Comment out this enum due to an issue with cpp-restsdk code generation.
    # enum:
    #   - "NONE"
    #   - "LOW"
    #   - "MEDIUM"
    #   - "HIGH"
    #   - "CRITICAL"
  TeleopCategory:
    description: "Category of a teleop notification"
    type: "string"
    # Comment out this enum due to an issue with cpp-restsdk code generation.
    # enum:
    #   - "NONE"
    #   - "SWO"
    #   - "GEO"
    #   - "CZ"
    #   - "CZ_ADV"
    #   - "EMERGENCY"
    #   - "FLAGGER"
    #   - "TRAFFIC_LIGHT"
    #   - "PATH"
    #   - "HEALTH"
    #   - "ENVIRONMENT"
    #   - "RIDER"
    #   - "COLLISION"
  ZrnMinimumReleaseStatus:
    type: "string"
    description: "Minimum ZRN release status that is supported by the on-vehicle planner"
    # Comment out this enum due to an issue with cpp-restsdk code generation.
    # enum:
    #   - "kAlpha"
    #   - "kBeta"
    #   - "kReleased"
    #   - "kPointToPoint"
    #   - "kZrnReleaseStatusUnknown"
  ErrorInfo:
    type: "object"
    description: "Resource representing the error information"
    properties:
      statusCode:
        type: "integer"
        description: "Error code."
        readOnly: true
      message:
        type: "string"
        description: "Message describing the error."
        readOnly: true
  LogEntry:
    type: "object"
    description: "A log entry"
  LogEntryList:
    type: "object"
    description: "A list of log entries."
    properties:
      items:
        type: array
        items:
          # Cause the code generator to use a generic JSON Object here,
          # We will need to manually parse the Object properties.
          oneOf:
            $ref: "#/definitions/LogEntry"
parameters:
  RobotId:
    name: "robotId"
    in: "path"
    type: "string"
    format: "uuid"
    description: "Id of the robot."
    required: true
  MissionId:
    name: "missionId"
    in: "path"
    type: "string"
    format: "uuid"
    description: "Id of the mission."
    required: true
  Limit:
    in: "query"
    name: "limit"
    type: "integer"
    description: "Number of records to limit"
    required: false
    default: 1
    minimum: 1
  Offset:
    in: "query"
    name: "offset"
    type: "integer"
    description: "Offset for fetching records in batches. Only returns records higher than offset. Default 0 (all)."
    required: false
    default: 0
    minimum: 0
