- id: schema/scalar
  anyOf:
    - number
    - boolean
    - string
    - enum: [null]

- id: schema/description
  anyOf:
    - string
    - object:
        closed: true
        properties:
          short: string
          long: string

- id: schema/base
  object:
    closed: true
    properties:
      additionalCompletions:
        arrayOf: string
      completions:
        arrayOf: string
      id: string
      hidden: boolean
      tags: object
      errorDescription: string
      description:
        ref: schema/description
      default: any

- id: schema/enum
  object:
    closed: true
    super:
      resolveRef: schema/base
    required:
      - enum
    properties:
      enum:
        anyOf:
          - arrayOf:
              ref: schema/scalar
          - object:
              closed: true
              super:
                resolveRef: schema/base
              properties:
                values:
                  arrayOf:
                    ref: schema/scalar

- id: schema/null
  anyOf:
    - enum: ["null"]
    - object:
        closed: true
        required:
          - "null"
        properties:
          "null":
            anyOf:
              - ref: schema/base

- id: schema/explicit-schema
  object:
    closed: true
    required:
      - "schema"
    super:
      resolveRef: schema/base
    properties:
      schema:
        ref: schema/schema

- id: schema/explicit-pattern-string
  object:
    closed: true
    super:
      resolveRef: schema/base
    required:
      - "pattern"
    properties:
      pattern: string

- id: schema/string
  anyOf:
    - enum: ["string", "path"]
    - ref: schema/explicit-pattern-string
    - object:
        closed: true
        super:
          resolveRef: schema/base
        required:
          - "path"
        properties:
          path:
            anyOf:
              - ref: schema/explicit-pattern-string
              - ref: schema/base
    - object:
        closed: true
        super:
          resolveRef: schema/base
        required:
          - "string"
        properties:
          string:
            anyOf:
              - ref: schema/explicit-pattern-string
              - ref: schema/base

- id: schema/number
  anyOf:
    - enum: ["number"]
    - object:
        closed: true
        super:
          resolveRef: schema/base
        required:
          - number
        properties:
          number:
            anyOf:
              - ref: schema/schema
              - ref: schema/base

- id: schema/boolean
  anyOf:
    - enum: ["boolean"]
    - object:
        closed: true
        required:
          - boolean
        super:
          resolveRef: schema/base
        properties:
          boolean:
            anyOf:
              - ref: schema/schema
              - ref: schema/base

- id: schema/resolve-ref
  object:
    closed: true
    required:
      - "resolveRef"
    properties:
      resolveRef: string

- id: schema/ref
  object:
    closed: true
    required:
      - "ref"
    properties:
      ref: string
      description:
        ref: schema/description
  # NB: schema/ref is _not_ a schema/base.

  #object:
  #  super:
  #    resolveRef: schema/base
  #  properties:
  #    ref: string

- id: schema/maybe-array-of
  object:
    closed: true
    required:
      - maybeArrayOf
    super:
      resolveRef: schema/base
    properties:
      maybeArrayOf:
        ref: schema/schema

- id: schema/array-of
  object:
    closed: true
    super:
      resolveRef: schema/base
    required:
      - "arrayOf"
    properties:
      arrayOf:
        anyOf:
          - ref: schema/schema
          - object:
              closed: true
              super:
                resolveRef: schema/base
              properties:
                length: number
                schema:
                  ref: schema/schema

- id: schema/all-of
  object:
    closed: true
    super:
      resolveRef: schema/base
    required:
      - "allOf"
    properties:
      allOf:
        anyOf:
          - arrayOf:
              ref: schema/schema
          - object:
              super:
                resolveRef: schema/base
              properties:
                schemas:
                  arrayOf:
                    ref: schema/schema

- id: schema/any-of
  object:
    closed: true
    super:
      resolveRef: schema/base
    required:
      - "anyOf"
    properties:
      anyOf:
        anyOf:
          - arrayOf:
              ref: schema/schema
          - object:
              super:
                resolveRef: schema/base
              properties:
                schemas:
                  arrayOf:
                    ref: schema/schema

- id: schema/record
  object:
    closed: true
    super:
      resolveRef: schema/base
    required:
      - "record"
    properties:
      record:
        anyOf:
          - object:
              additionalProperties:
                ref: schema/schema
          - object:
              closed: true
              super:
                resolveRef: schema/base
              properties:
                properties:
                  object:
                    additionalProperties:
                      ref: schema/schema
              required: [properties]

- id: schema/object
  anyOf:
    - enum: ["object"]
    - object:
        closed: true
        super:
          resolveRef: schema/base
        required:
          - "object"
        properties:
          object:
            object:
              super:
                resolveRef: schema/base
              closed: true
              properties:
                namingConvention:
                  anyOf:
                    - enum: ["ignore"]
                    - arrayOf:
                        enum:
                          # because this particular setup is especially likely to lead to typos,
                          # we support all naming conventions in describing naming conventions
                          - "camelCase"
                          - "camel-case"
                          - "camel_case"
                          - "capitalizationCase"
                          - "capitalization-case"
                          - "capitalization_case"
                          - "underscoreCase"
                          - "underscore-case"
                          - "underscore_case"
                          - "snakeCase"
                          - "snake-case"
                          - "snake_case"
                          - "dashCase"
                          - "dash-case"
                          - "dash_case"
                          - "kebabCase"
                          - "kebab-case"
                          - "kebab_case"
                properties:
                  object:
                    additionalProperties:
                      ref: schema/schema
                patternProperties:
                  object:
                    additionalProperties:
                      ref: schema/schema
                propertyNames:
                  ref: schema/schema
                additionalProperties:
                  ref: schema/schema
                super:
                  maybeArrayOf:
                    ref: schema/schema
                required:
                  anyOf:
                    - enum: ["all"]
                    - arrayOf: string
                closed: boolean
                description:
                  ref: schema/description
                completions:
                  arrayOf: string

- id: schema/schema
  anyOf:
    - ref: schema/enum
    - ref: schema/null
    - ref: schema/explicit-schema
    - ref: schema/string
    - ref: schema/number
    - ref: schema/boolean
    - ref: schema/ref
    - ref: schema/resolve-ref
    - ref: schema/any-of
    - ref: schema/array-of
    - ref: schema/maybe-array-of
    - ref: schema/all-of
    - ref: schema/record
    - ref: schema/object
    - enum: [null, "any"]
  description: "be a yaml schema"

- id: schema/schema-field
  object:
    properties:
      name: string
      schema:
        ref: schema/schema
      hidden: boolean
      alias: string
      disabled:
        maybeArrayOf: string
      enabled:
        maybeArrayOf: string
      description:
        ref: schema/description
      tags: object
      errorMessage: string
    namingConvention: ignore
    required: ["name", "schema", "description"]
    propertyNames:
      enum:
        - name
        - schema
        - hidden
        - alias
        - disabled
        - enabled
        - description
        - tags
        - errorMessage
        - default # no schema, but entry allowed
