#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.
#

---
paths:
  /v1/{prefix}/namespaces/{namespace}/tables/{table}/notifications:
    parameters:
      - $ref: '../iceberg-rest-catalog-open-api.yaml#/components/parameters/prefix'
      - $ref: '../iceberg-rest-catalog-open-api.yaml#/components/parameters/namespace'
      - $ref: '../iceberg-rest-catalog-open-api.yaml#/components/parameters/table'

    post:
      tags:
        - Catalog API
      summary: Sends a notification to the table
      operationId: sendNotification
      requestBody:
        description:
          The request containing the notification to be sent.
        
          For each table, Polaris will reject any notification where the timestamp in the request body
          is older than or equal to the most recent time Polaris has already processed for the table.
          The responsibility of ensuring the correct order of timestamps for a sequence of notifications 
          lies with the caller of the API. This includes managing potential clock skew or inconsistencies 
          when notifications are sent from multiple sources.

          A VALIDATE request behaves like a dry-run of a CREATE or UPDATE request up to but not including
          loading the contents of a metadata file; this includes validations of permissions, the specified
          metadata path being within ALLOWED_LOCATIONS, having an EXTERNAL catalog, etc. The intended use
          case for a VALIDATE notification is to allow a remote catalog to pre-validate the general
          settings of a receiving catalog against an intended new table location before possibly creating
          a table intended for sending notifications in the remote catalog at all. For a VALIDATE request,
          the specified metadata-location can either be a prospective full metadata file path, or a
          relevant parent directory of the intended table to validate against ALLOWED_LOCATIONS.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NotificationRequest'
        required: true
      responses:
        204:
          description: Success, no content
        400:
          $ref: '../iceberg-rest-catalog-open-api.yaml#/components/responses/BadRequestErrorResponse'
        401:
          $ref: '../iceberg-rest-catalog-open-api.yaml#/components/responses/UnauthorizedResponse'
        403:
          $ref: '../iceberg-rest-catalog-open-api.yaml#/components/responses/ForbiddenResponse'
        404:
          description:
            Not Found - NoSuchTableException, table to load does not exist
          content:
            application/json:
              schema:
                $ref: '../iceberg-rest-catalog-open-api.yaml#/components/schemas/IcebergErrorResponse'
              examples:
                TableToLoadDoesNotExist:
                  $ref: '../iceberg-rest-catalog-open-api.yaml#/components/examples/NoSuchTableError'
        409:
          description:
            Conflict - The timestamp of the received notification is older than or equal to the 
            most recent timestamp Polaris has already processed for the specified table.
          content:
            application/json:
              schema:
                $ref: '../iceberg-rest-catalog-open-api.yaml#/components/schemas/IcebergErrorResponse'
              example:
                $ref: '#/components/examples/OutOfOrderNotificationError'
        419:
          $ref: '../iceberg-rest-catalog-open-api.yaml#/components/responses/AuthenticationTimeoutResponse'
        503:
          $ref: '../iceberg-rest-catalog-open-api.yaml#/components/responses/ServiceUnavailableResponse'
        5XX:
          $ref: '../iceberg-rest-catalog-open-api.yaml#/components/responses/ServerErrorResponse'

components:
  schemas:
    NotificationRequest:
      required:
        - notification-type
        - payload
      properties:
        notification-type:
          $ref: '#/components/schemas/NotificationType'
        payload:
          $ref: '#/components/schemas/TableUpdateNotification'

    NotificationType:
      type: string
      enum:
        - UNKNOWN
        - CREATE
        - UPDATE
        - DROP
        - VALIDATE

    TableUpdateNotification:
      type: object
      required:
        - table-name
        - timestamp
        - table-uuid
        - metadata-location
      properties:
        table-name:
          type: string
        timestamp:
          type: integer
          format: int64
        table-uuid:
          type: string
        metadata-location:
          type: string
        metadata:
          $ref: '../iceberg-rest-catalog-open-api.yaml#/components/schemas/TableMetadata'

  examples:
    OutOfOrderNotificationError:
      summary:
        The timestamp of the received notification is older than or equal to the most recent timestamp
        Polaris has already processed for the specified table.
      value: {
        "error": {
          "message": "A notification with a newer timestamp has been admitted for table",
          "type": "AlreadyExistsException",
          "code": 409
        }
      }
