{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Babbage Model",
    "type": "object",
    "format": "valid_hierarchies",
    "properties": {
        "fact_table": {
            "$ref": "#/definitions/table"
        },
        "measures": {
            "$ref": "#/definitions/measures"
        },
        "dimensions": {
            "$ref": "#/definitions/dimensions"
        },
        "hierarchies": {
            "$ref": "#/definitions/hierarchies"
        },
        "joins": {
            "type": "array"
        }
    },
    "required": [
        "measures",
        "dimensions",
        "fact_table"
    ],
    "definitions": {
        "label": {
            "type": "string",
            "minLength": 2,
            "maxLength": 500
        },
        "description": {
            "type": "string",
            "minLength": 0,
            "maxLength": 1000,
            "default": ""
        },
        "column": {
            "type": "string",
            "minLength": 2,
            "maxLength": 250
        },
        "table": {
            "type": "string",
            "minLength": 2,
            "maxLength": 250,
            "pattern": "^[a-zA-Z][a-zA-Z0-9_\\-]*[a-zA-Z0-9]$"
        },
        "dimensions": {
            "type": "object",
            "patternProperties": {
                "^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$": {
                    "$ref": "#/definitions/dimension"
                }
            },
            "additionalProperties": false
        },
        "dimension": {
            "type": "object",
            "format": "attribute_exists",
            "properties": {
                "label": {
                    "$ref": "#/definitions/label"
                },
                "description": {
                    "$ref": "#/definitions/description"
                },
                "label_attribute": {
                    "type": "string",
                    "pattern": "^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$"
                },
                "key_attribute": {
                    "type": "string",
                    "pattern": "^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$"
                },
                "attributes": {
                    "$ref": "#/definitions/attributes"
                }
            },
            "required": [
                "label",
                "attributes",
                "key_attribute"
            ]
        },
        "attributes": {
            "type": "object",
            "minProperties": 1,
            "patternProperties": {
                "^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$": {
                    "$ref": "#/definitions/attribute"
                }
            },
            "additionalProperties": false
        },
        "attribute": {
            "type": "object",
            "properties": {
                "label": {
                    "$ref": "#/definitions/label"
                },
                "description": {
                    "$ref": "#/definitions/description"
                },
                "column": {
                    "$ref": "#/definitions/column"
                }
            },
            "required": [
                "label",
                "column"
            ]
        },
        "measures": {
            "type": "object",
            "minProperties": 1,
            "patternProperties": {
                "^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$": {
                    "$ref": "#/definitions/measure"
                }
            },
            "additionalProperties": false
        },
        "aggregates": {
            "type": "array",
            "items": {
                "type": "string",
                "enum": [
                    "sum",
                    "max",
                    "min",
                    "avg",
                    "count"
                ]
            },
            "default": [
                "sum"
            ],
            "minItems": 1,
            "_uniqueItems": true
        },
        "measure": {
            "type": "object",
            "properties": {
                "label": {
                    "$ref": "#/definitions/label"
                },
                "description": {
                    "$ref": "#/definitions/description"
                },
                "aggregates": {
                    "$ref": "#/definitions/aggregates"
                },
                "column": {
                    "$ref": "#/definitions/column"
                }
            },
            "required": [
                "label",
                "column"
            ]
        },
        "hierarchies": {
            "type": "object",
            "patternProperties": {
                "^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$": {
                    "$ref": "#/definitions/hierarchy"
                }
            },
            "additionalProperties": false
        },
        "hierarchy": {
            "type": "object",
            "properties": {
                "label": {
                    "$ref": "#/definitions/label"
                },
                "levels": {
                    "$ref": "#/definitions/levels"
                }
            },
            "required": [
                "levels"
            ]
        },
        "levels": {
            "type": "array",
            "items": {
                "$ref": "#/definitions/level"
            },
            "minItems": 1,
            "_uniqueItems": true
        },
        "level": {
            "type": "string"
        }
    }
}