{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://json.schemastore.org/openhab-5.1.json",
  "$defs": {
    "bool_value_type": { "enum": [true, false] },
    "thing_uid": {
      "type": "string",
      "pattern": "^[A-Za-z0-9]([\\w-]+:)+[\\w-]+$"
    },
    "item_type_enum": {
      "type": "string",
      "enum": [
        "Call",
        "Color",
        "Contact",
        "DateTime",
        "Dimmer",
        "Group",
        "Image",
        "Location",
        "Number",
        "Player",
        "Rollershutter",
        "String",
        "Switch"
      ]
    },
    "item_dimension_type": { "type": "string" },
    "config_value_type": {
      "oneOf": [
        { "$ref": "#/$defs/bool_value_type" },
        { "type": "number" },
        { "type": "string" }
      ]
    },

    "key_value_config_type": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^[A-Za-z]\\w*$": { "$ref": "#/$defs/config_value_type" }
      }
    },
    "key_array_value_config_type": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^[A-Za-z]\\w*$": {
          "oneOf": [
            { "$ref": "#/$defs/config_value_type" },
            {
              "type": "array",
              "items": { "$ref": "#/$defs/config_value_type" }
            }
          ]
        }
      }
    }
  },
  "title": "openHAB 5.1",
  "description": "Schema for openHAB configuration files. Implements version 5.1",
  "type": "object",
  "additionalProperties": false,
  "required": ["version"],
  "properties": {
    "version": { "type": "integer", "const": 1 },
    "things": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^[A-Za-z0-9]([\\w-]+:)+[\\w-]+$": {
          "type": "object",
          "properties": {
            "isBridge": { "$ref": "#/$defs/bool_value_type" },
            "bridge": { "$ref": "#/$defs/thing_uid" },
            "location": { "type": "string" },
            "config": { "$ref": "#/$defs/key_value_config_type" },
            "channels": {
              "type": "object",
              "additionalProperties": false,
              "patternProperties": {
                "^.+$": {
                  "type": "object",
                  "properties": {
                    "type": { "type": "string" },
                    "kind": { "enum": ["state", "trigger"] },
                    "itemType": { "$ref": "#/$defs/item_type_enum" },
                    "itemDimension": { "$ref": "#/$defs/item_dimension_type" },
                    "label": { "type": "string" },
                    "description": { "type": "string" },
                    "config": { "$ref": "#/$defs/key_array_value_config_type" }
                  },
                  "allOf": [
                    {
                      "if": { "required": ["type"] },
                      "then": {
                        "not": {
                          "anyOf": [
                            { "required": ["kind"] },
                            { "required": ["itemType"] }
                          ]
                        }
                      }
                    },
                    {
                      "if": { "type": "object", "required": ["itemDimension"] },
                      "then": {
                        "properties": { "itemType": { "const": "Number" } }
                      }
                    },
                    {
                      "if": {
                        "type": "object",
                        "properties": {
                          "itemType": { "not": { "const": "Number" } }
                        }
                      },
                      "then": { "not": { "required": ["itemDimension"] } }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "items": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^[a-zA-Z_][a-zA-Z0-9_]*$": {
          "type": "object",
          "properties": {
            "type": { "$ref": "#/$defs/item_type_enum" },
            "dimension": { "type": "string" },
            "group": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "type": { "$ref": "#/$defs/item_type_enum" },
                "dimension": { "type": "string" },
                "function": {
                  "type": "string",
                  "enum": [
                    "EQUALITY",
                    "AND",
                    "OR",
                    "NAND",
                    "NOR",
                    "XOR",
                    "SUM",
                    "AVG",
                    "MEDIAN",
                    "MIN",
                    "MAX",
                    "COUNT",
                    "LATEST",
                    "EARLIEST"
                  ]
                },
                "parameters": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "allOf": [
                {
                  "if": { "type": "object", "required": ["dimension"] },
                  "then": { "properties": { "type": { "const": "Number" } } }
                },
                {
                  "if": {
                    "type": "object",
                    "properties": { "type": { "not": { "const": "Number" } } }
                  },
                  "then": { "not": { "required": ["dimension"] } }
                }
              ]
            },
            "label": { "type": "string" },
            "icon": { "type": "string" },
            "groups": {
              "type": "array",
              "items": {
                "type": "string",
                "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
              }
            },
            "tags": {
              "type": "array",
              "items": {
                "type": "string",
                "pattern": "^[a-zA-Z_][a-zA-Z0-9_-]*$"
              }
            },
            "format": { "type": "string" },
            "unit": { "type": "string" },
            "autoupdate": { "$ref": "#/$defs/bool_value_type" },
            "channel": { "type": "string" },
            "channels": {
              "type": "object",
              "patternProperties": {
                "^.*$": { "$ref": "#/$defs/key_array_value_config_type" }
              }
            },
            "metadata": {
              "type": "object",
              "patternProperties": {
                "^.*$": {
                  "type": "object",
                  "properties": {
                    "value": { "$ref": "#/$defs/config_value_type" },
                    "config": { "$ref": "#/$defs/key_value_config_type" }
                  }
                }
              }
            }
          },
          "allOf": [
            {
              "if": { "type": "object", "required": ["dimension"] },
              "then": { "properties": { "type": { "const": "Number" } } }
            },
            {
              "if": {
                "type": "object",
                "properties": { "type": { "not": { "const": "Number" } } }
              },
              "then": { "not": { "required": ["dimension"] } }
            },
            {
              "not": {
                "required": ["channel", "channels"]
              }
            }
          ]
        }
      }
    },
    "tags": {
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^(Location|Equipment|Point|Property)_([A-Z][A-Za-z0-9_]+)*[A-Z][A-Za-z0-9_]*$": {
          "type": "object",
          "properties": {
            "label": { "type": "string" },
            "description": { "type": "string" },
            "synonyms": {
              "type": "array",
              "items": { "type": "string" }
            }
          }
        }
      }
    }
  }
}
