# 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:
  /metalakes:

    get:
      tags:
        - metalake
      summary: List metalakes
      operationId: listMetalakes
      description: Returns a list of all metalakes.
      responses:
        "200":
          $ref: "#/components/responses/ListMetalakesResponse"
        "400":
          $ref: "./openapi.yaml#/components/responses/BadRequestErrorResponse"
        "5xx":
          $ref: "./openapi.yaml#/components/responses/ServerErrorResponse"

    post:
      tags:
        - metalake
      summary: Create metalake
      operationId: createMetalake
      description: Creates a new metalake
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MetalakeCreateRequest"
            examples:
              MetalakeCreate:
                $ref: "#/components/examples/MetalakeCreate"

      responses:
        "200":
          $ref: "#/components/responses/MetalakeResponse"
        "409":
          description: Conflict - The target metalake already exists
          content:
            application/vnd.gravitino.v1+json:
              schema:
                $ref: "./openapi.yaml#/components/schemas/ErrorModel"
              examples:
                MetalakeAlreadyExistsException:
                  $ref: "#/components/examples/MetalakeAlreadyExistsException"
        "5xx":
          $ref: "./openapi.yaml#/components/responses/ServerErrorResponse"

  /metalakes/{name}:
    parameters:
      - name: name
        in: path
        description: The name of the metalake to retrieve
        required: true
        schema:
          type: string
    get:
      tags:
        - metalake
      summary: Get metalake
      operationId: loadMetalake
      description: Returns a metalake information by given metalake name
      responses:
        "200":
          $ref: "#/components/responses/MetalakeResponse"
        "404":
          description: Not Found - The metalake does not exist
          content:
            application/vnd.gravitino.v1+json:
              schema:
                $ref: "./openapi.yaml#/components/schemas/ErrorModel"
              examples:
                NoSuchMetalakeException:
                  $ref: "#/components/examples/NoSuchMetalakeException"
        "5xx":
          $ref: "./openapi.yaml#/components/responses/ServerErrorResponse"

    put:
      tags:
        - metalake
      summary: Update metalake
      operationId: alterMetalake
      description: Alters a specified metalake
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MetalakeUpdatesRequest"
      responses:
        "200":
          $ref: "#/components/responses/MetalakeResponse"
        "404":
          description: Not Found - The metalake does not exist
          content:
            application/vnd.gravitino.v1+json:
              schema:
                $ref: "./openapi.yaml#/components/schemas/ErrorModel"
              examples:
                NoSuchMetalakeException:
                  $ref: "#/components/examples/NoSuchMetalakeException"
        "409":
          description: Conflict - The target (metalake)name already exists
          content:
            application/vnd.gravitino.v1+json:
              schema:
                $ref: "./openapi.yaml#/components/schemas/ErrorModel"
              examples:
                MetalakeAlreadyExistsException:
                  $ref: "#/components/examples/MetalakeAlreadyExistsException"
        "500":
          description:
            Internal server error. It is possible that the server
            encountered a storage issue.
          content:
            application/vnd.gravitino.v1+json:
              schema:
                $ref: "./openapi.yaml#/components/schemas/ErrorModel"

    delete:
      tags:
        - metalake
      summary: Drop metalake
      operationId: dropMetalake
      description: Drops a specified metalake
      responses:
        "200":
          $ref: "./openapi.yaml#/components/responses/DropResponse"
        "400":
          $ref: "./openapi.yaml#/components/responses/BadRequestErrorResponse"
        "5xx":
          $ref: "./openapi.yaml#/components/responses/ServerErrorResponse"

components:

  schemas:

    MetalakeCreateRequest:
      type: object
      required:
        - name
      properties:
        name:
          type: string
          description: The name of the metalake
        comment:
          type: string
          description: A comment about the metalake
          nullable: true
        properties:
          type: object
          description: Configured string to string map of properties for the metalake
          nullable: true
          default: {}
          additionalProperties:
            type: string

    MetalakeUpdatesRequest:
      type: object
      required:
        - updates
      properties:
        updates:
          type: array
          items:
            $ref: "#/components/schemas/MetalakeUpdateRequest"

    MetalakeUpdateRequest:
      oneOf:
        - $ref: "#/components/schemas/RenameMetalakeRequest"
        - $ref: "#/components/schemas/UpdateMetalakeCommentRequest"
        - $ref: "#/components/schemas/SetMetalakePropertyRequest"
        - $ref: "#/components/schemas/RemoveMetalakePropertyRequest"
      discriminator:
        propertyName: "@type"
        mapping:
          rename: "#/components/schemas/RenameMetalakeRequest"
          updateComment: "#/components/schemas/UpdateMetalakeCommentRequest"
          setProperty: "#/components/schemas/SetMetalakePropertyRequest"
          removeProperty: "#/components/schemas/RemoveMetalakePropertyRequest"

    RenameMetalakeRequest:
      type: object
      required:
        - "@type"
        - newName
      properties:
        "@type":
          type: string
          enum:
            - rename
        newName:
          type: string
          description: The new name of the metalake
      example: {
        "@type": "rename",
        "newName": "my_metalake_new"
      }

    UpdateMetalakeCommentRequest:
      type: object
      required:
        - "@type"
        - newComment
      properties:
        "@type":
          type: string
          enum:
            - updateComment
        newComment:
          type: string
          description: The new comment of the metalake
      example: {
        "@type": "updateComment",
        "newComment": "This is my new metalake comment"
      }

    SetMetalakePropertyRequest:
      type: object
      required:
        - "@type"
        - property
        - value
      properties:
        "@type":
          type: string
          enum:
            - setProperty
        property:
          type: string
          description: The property to set
        value:
          type: string
          description: The value to set
      example: {
        "@type": "setProperty",
        "property": "key1",
        "value": "value1_new"
      }

    RemoveMetalakePropertyRequest:
      type: object
      required:
        - "@type"
        - property
      properties:
        "@type":
          type: string
          enum:
            - removeProperty
        property:
          type: string
          description: The property to remove
      example: {
        "@type": "removeProperty",
        "property": "key2"
      }

    Metalake:
      type: object
      description:
        Gravitino Metalake is the top-level metadata repository for users.
        It contains a list of catalogs as sub-level metadata collections.
        With GravitinoMetaLake, users can list, create, load, alter and
        drop a catalog with specified identifier.
      required:
        - name
      properties:
        name:
          type: string
          description: The name of the Metalake
        comment:
          type: string
          description: A comment about the Metalake
          nullable: true
        audit:
          $ref: "./openapi.yaml#/components/schemas/Audit"
        properties:
          type: object
          description: Configured string to string map of properties for the Metalake
          default: { }
          additionalProperties:
            type: string
      example: {
        "name": "my_metalake",
        "comment": "This is my metalake",
        "properties": {
          "key1": "value1",
          "key2": "value2",
          "gravitino.identifier": "gravitino.v1.uid4516733622157792920"
        },
        "audit": {
          "creator": "gravitino",
          "createTime": "2023-12-07T14:04:17.349Z"
        }
      }

  responses:

    ListMetalakesResponse:
      description: Returns a list of all metalakes.
      content:
        application/vnd.gravitino.v1+json:
          schema:
            type: object
            properties:
              code:
                type: integer
                format: int32
                description: Status code of the response
                enum:
                  - 0
                example: 0
              metalakes:
                type: array
                description: A list of metalake objects
                items:
                  $ref: "#/components/schemas/Metalake"

    MetalakeResponse:
      description: Returns included metalake object.
      content:
        application/vnd.gravitino.v1+json:
          schema:
            type: object
            properties:
              code:
                type: integer
                format: int32
                description: Status code of the response
                enum:
                  - 0
              metalake:
                $ref: "#/components/schemas/Metalake"
          examples:
            MetalakeResponse:
              $ref: "#/components/examples/MetalakeResponse"

  examples:

    MetalakeAlreadyExistsException:
      value: {
        "code": 1004,
        "type": "MetalakeAlreadyExistsException",
        "message": "Failed to operate metalake(s) [my_metalake] operation [CREATE], reason [MetalakeAlreadyExistsException]",
        "stack": [
          "org.apache.gravitino.exceptions.MetalakeAlreadyExistsException: Metalake my_metalake already exists",
          "..."
        ]
      }

    NoSuchMetalakeException:
      value: {
        "code": 1003,
        "type": "NoSuchMetalakeException",
        "message": "Failed to operate metalake(s) [test] operation [LOAD], reason [NoSuchMetalakeException]",
        "stack": [
          "org.apache.gravitino.exceptions.NoSuchMetalakeException: Metalake test does not exist",
          "..." ]
      }

    MetalakeCreate:
      value: {
        "name": "my_metalake",
        "comment": "This is my metalake",
        "properties": {
          "key1": "value1",
          "key2": "value2"
        }
      }

    MetalakeResponse:
      value: {
        "code": 0,
        "metalake": {
          "name": "my_metalake",
          "comment": "This is my metalake",
          "properties": {
            "key1": "value1",
            "key2": "value2",
            "gravitino.identifier": "gravitino.v1.uid2062071866014250017"
          },
          "audit": {
            "creator": "gravitino",
            "createTime": "2023-12-06T14:21:24.982Z"
          }
        }
      }
