{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://azerty.global/docs/automation/v0.1/schema.json",
  "title": "AZERTY Global automation specification",
  "type": "object",
  "additionalProperties": false,
  "required": ["$schema", "schemaVersion", "license", "layout", "modifierModel", "characters", "deadKeys", "controls"],
  "properties": {
    "$schema": { "const": "https://azerty.global/docs/automation/v0.1/schema.json" },
    "schemaVersion": { "const": "0.1.0" },
    "license": { "const": "EUPL-1.2" },
    "layout": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "name", "version", "geometry", "platforms", "status", "capabilities"],
      "properties": {
        "id": { "type": "string" },
        "name": { "const": "AZERTY Global" },
        "version": { "type": "string" },
        "geometry": { "const": "ISO" },
        "platforms": {
          "type": "array",
          "const": ["windows", "macos", "linux"]
        },
        "status": { "const": "logical-common" },
        "capabilities": {
          "type": "object",
          "additionalProperties": false,
          "required": ["capsLock", "altGr"],
          "properties": {
            "capsLock": { "type": "boolean" },
            "altGr": { "type": "boolean" }
          }
        }
      }
    },
    "modifierModel": {
      "type": "object",
      "additionalProperties": false,
      "required": ["kind", "modifiers", "usbHidScancodes"],
      "properties": {
        "kind": { "const": "logical" },
        "modifiers": { "const": ["Shift", "AltGr"] },
        "usbHidScancodes": { "const": false }
      }
    },
    "characters": {
      "type": "object",
      "patternProperties": {
        "^U\\+[0-9A-F]{4,6}$": { "$ref": "#/$defs/character" }
      },
      "additionalProperties": false
    },
    "deadKeys": {
      "type": "object",
      "patternProperties": {
        "^dk_[a-z_]+$": {
          "type": "object",
          "additionalProperties": false,
          "required": ["methods"],
          "properties": { "methods": { "$ref": "#/$defs/deadKeyActivationMethods" } }
        }
      },
      "additionalProperties": false
    },
    "controls": {
      "type": "object",
      "additionalProperties": false,
      "required": ["U+0009", "U+000A", "U+000D"],
      "properties": {
        "U+0009": { "$ref": "#/$defs/control" },
        "U+000A": { "$ref": "#/$defs/control" },
        "U+000D": { "$ref": "#/$defs/control" }
      }
    }
  },
  "$defs": {
    "character": {
      "type": "object",
      "additionalProperties": false,
      "required": ["codePoint", "glyph", "unicodeNames", "aliases", "methods"],
      "properties": {
        "codePoint": { "type": "string", "pattern": "^U\\+[0-9A-F]{4,6}$" },
        "glyph": { "type": "string", "minLength": 1, "maxLength": 1 },
        "unicodeNames": {
          "type": "object",
          "additionalProperties": false,
          "required": ["en", "fr"],
          "properties": {
            "en": { "type": ["string", "null"] },
            "fr": { "type": ["string", "null"] }
          }
        },
        "aliases": {
          "type": "object",
          "additionalProperties": false,
          "required": ["fr", "en"],
          "properties": {
            "fr": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
            "en": { "type": "array", "items": { "type": "string" }, "uniqueItems": true }
          }
        },
        "methods": { "$ref": "#/$defs/characterMethods" }
      }
    },
    "control": {
      "type": "object",
      "additionalProperties": false,
      "required": ["name", "codePoint", "character", "methods"],
      "properties": {
        "name": { "enum": ["TAB", "LF", "CR"] },
        "codePoint": { "type": "string", "pattern": "^U\\+[0-9A-F]{4,6}$" },
        "character": { "type": "string", "minLength": 1, "maxLength": 1 },
        "methods": { "$ref": "#/$defs/controlMethods" }
      }
    },
    "methods": {
      "type": "array",
      "minItems": 1,
      "uniqueItems": true,
      "contains": {
        "type": "object",
        "required": ["recommendedForAutomation"],
        "properties": { "recommendedForAutomation": { "const": true } }
      },
      "minContains": 1,
      "maxContains": 1
    },
    "characterMethods": {
      "allOf": [
        { "$ref": "#/$defs/methods" },
        {
          "type": "array",
          "items": { "$ref": "#/$defs/characterMethod" }
        }
      ]
    },
    "deadKeyActivationMethods": {
      "allOf": [
        { "$ref": "#/$defs/methods" },
        {
          "type": "array",
          "items": { "$ref": "#/$defs/deadKeyActivationMethod" }
        }
      ]
    },
    "controlMethods": {
      "allOf": [
        { "$ref": "#/$defs/methods" },
        {
          "type": "array",
          "items": { "$ref": "#/$defs/controlMethod" }
        }
      ]
    },
    "characterMethod": {
      "allOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "required": ["kind", "preconditions", "steps", "recommendedForAutomation"],
          "properties": {
            "kind": { "enum": ["direct", "deadKey"] },
            "preconditions": { "$ref": "#/$defs/preconditions" },
            "steps": { "type": "array" },
            "recommendedForAutomation": { "type": "boolean" }
          }
        },
        {
          "type": "object",
          "oneOf": [
            {
              "type": "object",
              "required": ["kind", "steps"],
              "properties": {
                "kind": { "const": "direct" },
                "steps": {
                  "type": "array",
                  "minItems": 1,
                  "maxItems": 1,
                  "prefixItems": [
                    { "$ref": "#/$defs/characterStep" }
                  ],
                  "items": false
                }
              }
            },
            {
              "type": "object",
              "required": ["kind", "steps"],
              "properties": {
                "kind": { "const": "deadKey" },
                "steps": {
                  "type": "array",
                  "minItems": 2,
                  "maxItems": 2,
                  "prefixItems": [
                    { "$ref": "#/$defs/deadKeyStep" },
                    { "$ref": "#/$defs/characterStep" }
                  ],
                  "items": false
                }
              }
            }
          ]
        }
      ]
    },
    "deadKeyActivationMethod": {
      "type": "object",
      "additionalProperties": false,
      "required": ["kind", "preconditions", "steps", "recommendedForAutomation"],
      "properties": {
        "kind": { "const": "deadKey" },
        "preconditions": { "$ref": "#/$defs/preconditions" },
        "steps": {
          "type": "array",
          "minItems": 1,
          "maxItems": 1,
          "prefixItems": [{ "$ref": "#/$defs/deadKeyStep" }],
          "items": false
        },
        "recommendedForAutomation": { "type": "boolean" }
      }
    },
    "controlMethod": {
      "type": "object",
      "additionalProperties": false,
      "required": ["kind", "preconditions", "steps", "recommendedForAutomation"],
      "properties": {
        "kind": { "const": "direct" },
        "preconditions": { "$ref": "#/$defs/preconditions" },
        "steps": {
          "type": "array",
          "minItems": 1,
          "maxItems": 1,
          "prefixItems": [{ "$ref": "#/$defs/controlStep" }],
          "items": false
        },
        "recommendedForAutomation": { "type": "boolean" }
      }
    },
    "preconditions": {
      "type": "object",
      "additionalProperties": false,
      "required": ["capsLock"],
      "properties": { "capsLock": { "enum": ["on", "off"] } }
    },
    "characterStep": {
      "type": "object",
      "additionalProperties": false,
      "required": ["role", "code", "modifiers"],
      "properties": {
        "role": { "const": "character" },
        "code": { "type": "string", "minLength": 1 },
        "modifiers": {
          "type": "array",
          "items": { "enum": ["Shift", "AltGr"] },
          "uniqueItems": true
        }
      }
    },
    "deadKeyStep": {
      "type": "object",
      "additionalProperties": false,
      "required": ["role", "code", "modifiers"],
      "properties": {
        "role": { "const": "deadKey" },
        "code": { "type": "string", "minLength": 1 },
        "modifiers": {
          "type": "array",
          "items": { "enum": ["Shift", "AltGr"] },
          "uniqueItems": true
        }
      }
    },
    "controlStep": {
      "type": "object",
      "additionalProperties": false,
      "required": ["role", "code", "modifiers"],
      "properties": {
        "role": { "const": "control" },
        "code": { "enum": ["Tab", "Enter"] },
        "modifiers": {
          "type": "array",
          "items": { "enum": ["Shift", "AltGr"] },
          "uniqueItems": true
        }
      }
    }
  }
}
