{
    "$schema": "http://json-schema.org/draft-07/schema",
    "title": "RGMP v2 Stream Definition Frame",
    "description": "JSON Schema for the initialization frame of the RGMP v2 protocol.",
    "type": "object",
    "required": [
        "protocol_name",
        "protocol_version",
        "device_id",
        "device_type",
        "timestamp_epoch",
        "groups"
    ],
    "properties": {
        "protocol_name": {
            "type": "string",
            "description": "Name of the protocol (e.g., 'RGMP')"
        },
        "protocol_version": {
            "type": "string",
            "description": "Protocol version (e.g., '2.0.0')"
        },
        "device_id": {
            "type": "integer",
            "minimum": 0,
            "description": "Unique identifier for the device/session"
        },
        "device_type": {
            "type": "string",
            "minLength": 1,
            "description": "Type of the device (e.g., 'smartgloves', 'smartsuit')"
        },
        "timestamp_epoch": {
            "type": "string",
            "enum": [
                "unix_epoch",
                "device_boot"
            ],
            "description": "Timestamp defining the epoch for all subsequent timestamps in data frames ('unix_epoch' or 'device_boot')"
        },
        "device_info": {
            "type": "object",
            "description": "Optional device metadata",
            "additionalProperties": true
        },
        "static_data": {
            "type": "array",
            "description": "List of static data entries (e.g., fixed transforms, calibration)",
            "items": {
                "$ref": "#/definitions/static_data_entry"
            }
        },
        "groups": {
            "type": "array",
            "description": "List of stream groups transmitting at specific rates",
            "items": {
                "$ref": "#/definitions/group_entry"
            },
            "minItems": 1
        }
    },
    "definitions": {
        "base_data_entry": {
            "type": "object",
            "required": [
                "data_type",
                "measure_type",
                "target_frame"
            ],
            "properties": {
                "data_type": {
                    "type": "string",
                    "pattern": "^(INT32|UINT32|INT64|UINT64|FLOAT|DOUBLE)(\\[\\d+(,\\d+)?\\])?$",
                    "description": "Valid types: INT32, UINT32, INT64, UINT64, FLOAT, DOUBLE, TYPE[N], or TYPE[N, M]. Dimensions N and M must each be >= 1."
                },
                "measure_type": {
                    "type": "string",
                    "pattern": "^(POSITION|ORIENTATION|TRANSFORM|ANGULAR_VELOCITY|LINEAR_VELOCITY|LINEAR_ACCELERATION|PROPER_ACCELERATION|MAGNETIC_FIELD|STATUS_FLAGS|CUSTOM)$",
                    "description": "Semantic meaning (one of POSITION, ORIENTATION, TRANSFORM, ANGULAR_VELOCITY, LINEAR_VELOCITY, LINEAR_ACCELERATION, PROPER_ACCELERATION, MAGNETIC_FIELD, STATUS_FLAGS, CUSTOM)"
                },
                "reference_frame": {
                    "type": "string",
                    "description": "(Optional) The coordinate frame the data is measured relative to"
                },
                "target_frame": {
                    "type": "string",
                    "description": "Name of the target object or sensor the data describes"
                },
                "custom_label": {
                    "type": "string",
                    "description": "Required when measure_type is CUSTOM; rejected on every other measure_type."
                },
                "bit_mapping": {
                    "type": "object",
                    "description": "Mapping of flag bits to names (used with STATUS_FLAGS)",
                    "patternProperties": {
                        "^[0-9]+$": {
                            "type": "string"
                        }
                    },
                    "additionalProperties": false
                }
            },
            "allOf": [
                {
                    "if": {
                        "properties": { "measure_type": { "const": "CUSTOM" } },
                        "required": ["measure_type"]
                    },
                    "then": {
                        "required": ["custom_label"]
                    },
                    "else": {
                        "not": { "required": ["custom_label"] }
                    }
                }
            ]
        },
        "static_data_entry": {
            "allOf": [
                {
                    "$ref": "#/definitions/base_data_entry"
                },
                {
                    "type": "object",
                    "required": [
                        "value"
                    ],
                    "properties": {
                        "value": {
                            "description": "The static value (scalar, array, or object) matching the data_type"
                        }
                    }
                }
            ]
        },
        "group_entry": {
            "type": "object",
            "required": [
                "name",
                "expected_rate_hz",
                "streams"
            ],
            "properties": {
                "name": {
                    "type": "string",
                    "description": "Human-readable name for the group"
                },
                "expected_rate_hz": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Expected update rate for this group (in Hz)"
                },
                "streams": {
                    "type": "array",
                    "description": "Ordered array of streams multiplexed into this group's binary payload",
                    "items": {
                        "$ref": "#/definitions/base_data_entry"
                    },
                    "minItems": 1
                }
            },
            "additionalProperties": false
        }
    }
}