{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "description": "Schema for ogrinfo -json output",

  "oneOf": [
    {
      "$ref": "#/definitions/dataset"
    }
  ],

  "definitions": {

    "dataset": {
      "type": "object",
      "properties": {
        "description": {
          "type": "string"
        },
        "driverShortName": {
          "type": "string"
        },
        "driverLongName": {
          "type": "string"
        },
        "layers": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/layer"
          }
        },
        "metadata": {
          "$ref": "#/definitions/metadata"
        },
        "domains": {
          "$ref": "#/definitions/domains"
        },
        "relationships": {
          "$ref": "#/definitions/relationships"
        },
        "rootGroup": {
          "$ref": "#/definitions/group"
        }
      },
      "required": [
        "layers",
        "metadata",
        "domains"
      ],
      "additionalProperties": false
    },

    "layer": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "geometryType": {
          "$comment": "Geometry type(s) as a string, e.g. 'Point', 'Line String', 'Polygon', etc. If the layer has multiple geometry types, they are separated by commas. This property is optional and is only present in summary mode when the 'geometryFields' property is omitted.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "metadata": {
          "$ref": "#/definitions/metadata"
        },
        "fidColumnName": {
          "type": "string"
        },
        "featureCount": {
          "type": "number"
        },
        "features": {
          "type": "array",
          "items": {
            "$ref": "https://geojson.org/schema/Feature.json"
          }
        },
        "fields": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/field"
          }
        },
        "geometryFields": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/geometryField"
          }
        }
      },
      "required": [
        "name"
      ],
      "additionalProperties": false
    },

    "metadata": {
      "type": "object",
      "$comment": "Object whose keys are metadata domain names. The empty string is a valid metadata domain name, and is used for the default domain.",
      "patternProperties": {
        "^.*$": {
          "$ref": "#/definitions/metadataDomain"
        }
      }
    },

    "metadataDomain": {
      "$comment": " The values of a metadadomain are key: string pairs, or arbitrary JSON objects for metadata domain names starting with the \"json:\" prefix.",
      "any": [
        {
          "type": "object"
        },
        {
          "type": "#/definitions/keyValueDict"
        }
      ]
    },

    "field": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "type": {
          "$ref": "#/definitions/fieldType"
        },
        "subType": {
          "$ref": "#/definitions/fieldSubType"
        },
        "width": {
          "type": "integer"
        },
        "precision": {
          "type": "integer"
        },
        "nullable": {
          "type": "boolean"
        },
        "uniqueConstraint": {
          "type": "boolean"
        },
        "defaultValue": {
          "type": "string"
        },
        "alias": {
          "type": "string"
        },
        "domainName": {
          "type": "string"
        },
        "comment": {
          "type": "string"
        },
        "timezone": {
          "type": "string",
          "pattern": "^(localtime|(mixed timezones)|UTC|((\\+|-)[0-9][0-9]:[0-9][0-9]))$"
        }
      },
      "required": [
        "name",
        "type",
        "nullable",
        "uniqueConstraint"
      ],
      "additionalProperties": false
    },

    "fieldType": {
      "enum": [
        "Integer",
        "Integer64",
        "Real",
        "String",
        "Binary",
        "IntegerList",
        "Integer64List",
        "RealList",
        "StringList",
        "Date",
        "Time",
        "DateTime"
      ]
    },

    "fieldSubType": {
      "enum": [
        "None",
        "Boolean",
        "Int16",
        "Float32",
        "JSON",
        "UUID"
      ]
    },

    "geometryField": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "type": {
          "pattern": "^(Geometry|((Multi)?Point)|((Multi)?LineString)|((Multi)?Polygon)|GeometryCollection|((Multi)?Curve)|((Multi)?Surface)|CircularString|CompoundCurve|CurvePolygon|Tin|PolyhedralSurface|Triangle)[Z]?[M]?$"
        },
        "nullable": {
          "type": "boolean"
        },
        "extent": {
          "type": "array",
          "items": {
            "type": "number",
            "minItems": 4,
            "maxItems": 4
          }
        },
        "extent3D": {
          "type": "array",
          "items": {
            "type": [
              "null",
              "number"
            ],
            "minItems": 6,
            "maxItems": 6
          }
        },
        "coordinateSystem": {
          "oneOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/definitions/coordinateSystem"
            }
          ]
        },
        "supportedSRSList": {
          "type": "array",
          "items": {
            "oneOf": [
              {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "object",
                    "properties": {
                      "authority": {
                        "type": "string"
                      },
                      "code": {
                        "type": "string"
                      }
                    }
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "object",
                "properties": {
                  "wkt": {
                    "type": "string"
                  }
                },
                "additionalProperties": false
              }
            ]
          }
        },
        "xyCoordinateResolution": {
          "type": "number"
        },
        "zCoordinateResolution": {
          "type": "number"
        },
        "mCoordinateResolution": {
          "type": "number"
        },
        "coordinatePrecisionFormatSpecificOptions": {
          "type": "object"
        }
      },
      "required": [
        "name",
        "type"
      ],
      "additionalProperties": false
    },

    "coordinateSystem": {
      "type": "object",
      "properties": {
        "wkt": {
          "type": "string"
        },
        "projjson": {
          "$ref": "https://proj.org/schemas/v0.5/projjson.schema.json"
        },
        "dataAxisToSRSAxisMapping": {
          "type": "array",
          "items": {
            "type": "number",
            "minItems": 2,
            "maxItems": 3
          }
        },
        "coordinateEpoch": {
          "type": "number"
        }
      },
      "required": [
        "wkt",
        "dataAxisToSRSAxisMapping"
      ],
      "additionalProperties": false
    },

    "domains": {
      "type": "object",
      "patternProperties": {
        "^.*$": {
          "$ref": "#/definitions/domain"
        }
      },
      "additionalProperties": false
    },

    "keyValueDict": {
      "type": "object",
      "patternProperties": {
        "^.*$": {}
      }
    },

    "domain": {
      "type": "object",
      "properties": {
        "description": {
          "type": "string"
        },
        "type": {
          "enum": [
            "coded",
            "range",
            "glob"
          ]
        },
        "fieldType": {
          "$ref": "#/definitions/fieldType"
        },
        "fieldSubType": {
          "$ref": "#/definitions/fieldSubType"
        },
        "glob": {
          "$comment": "only present when type=coded",
          "type": "string"
        },
        "codedValues": {
          "$comment": "only present when type=coded",
          "$ref": "#/definitions/keyValueDict"
        },
        "splitPolicy": {
          "enum": [
            "default value",
            "duplicate",
            "geometry ratio"
          ]
        },
        "mergePolicy": {
          "enum": [
            "default value",
            "sum",
            "geometry weighted"
          ]
        },
        "minValue": {
          "$comment": "only present when type=range",
          "any": [
            {
              "type": "string "
            },
            {
              "type": "number"
            }
          ]
        },
        "minValueIncluded": {
          "$comment": "only present when type=range",
          "type": "boolean"
        },
        "maxValue": {
          "$comment": "only present when type=range",
          "any": [
            {
              "type": "string "
            },
            {
              "type": "number"
            }
          ]
        },
        "maxValueIncluded": {
          "$comment": "only present when type=range",
          "type": "boolean"
        }
      },
      "required": [
        "type",
        "fieldType",
        "splitPolicy",
        "mergePolicy"
      ],
      "additionalProperties": false
    },

    "group": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "layerNames": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "groups": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/group"
          }
        }
      },
      "required": [
        "layerNames",
        "groups"
      ],
      "additionalProperties": false
    },

    "relationships": {
      "type": "object",
      "patternProperties": {
        "^.*$": {
          "$ref": "#/definitions/relationship"
        }
      },
      "additionalProperties": false
    },

    "relationship": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "Composite",
            "Association",
            "Aggregation"
          ]
        },
        "related_table_type": {
          "type": "string"
        },
        "cardinality": {
          "type": "string",
          "enum": [
            "OneToOne",
            "OneToMany",
            "ManyToOne",
            "ManyToMany"
          ]
        },
        "left_table_name": {
          "type": "string"
        },
        "right_table_name": {
          "type": "string"
        },
        "left_table_fields": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "right_table_fields": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "mapping_table_name": {
          "type": "string"
        },
        "left_mapping_table_fields": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "right_mapping_table_fields": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "forward_path_label": {
          "type": "string"
        },
        "backward_path_label": {
          "type": "string"
        }
      },
      "required": [
        "type",
        "related_table_type",
        "cardinality",
        "left_table_name",
        "right_table_name",
        "left_table_fields",
        "right_table_fields",
        "forward_path_label",
        "backward_path_label"
      ],
      "additionalProperties": false
    }
  }
}
