{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$id": "vote-definition/vote",
    "type": "object",
    "required": ["phasesBlockHeights", "eligibleVotersChainId", "type", "config"],
    "definitions": {
        "weightedUnweighted": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
                "weighted": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1
                },
                "unweighted": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1
                }
            }
        },
        "type0": {
            "properties": {
                "type": {
                    "const": 0
                },
                "config": {
                    "required": ["computeResultsAgainst", "winnerCriteria"],
                    "properties": {
                        "options": {
                            "minItems": 2,
                            "maxItems": 2
                        },
                        "winnerCriteria": {
                            "properties": {
                                "minSupport": {
                                    "minProperties": 1,
                                    "maxProperties": 1,
                                    "propertyNames": {
                                        "enum": {
                                            "$data": "3/options"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "type1": {
            "properties": {
                "type": {
                    "const": 1
                },
                "config": {
                    "required": ["computeResultsAgainst", "winnerCriteria"]
                }
            }
        },
        "type2": {
            "properties": {
                "type": {
                    "const": 2
                },
                "config": {
                    "not": {
                        "anyOf": [
                            { "required": ["winnerCriteria"] },
                            { "required": ["computeResultsAgainst"] }
                        ]
                    }
                }
            }
        }
    },
    "additionalProperties": false,
    "properties": {
        "phasesBlockHeights": {
            "type": "object",
            "required": ["commitStart", "commitEnd", "revealEnd"],
            "additionalProperties": false,
            "properties": {
                "commitStart": {
                    "type": "integer",
                    "minimum": 0
                },
                "commitEnd": {
                    "type": "integer",
                    "minimum": {
                        "$data": "1/commitStart"
                    }
                },
                "revealEnd": {
                    "type": "integer",
                    "exclusiveMinimum": {
                        "$data": "1/commitEnd"
                    }
                }
            }
        },
        "eligibleVotersChainId": {
            "type": "string",
            "pattern": "^[0-9a-f]{64}$"
        },
        "type": {
            "enum": [0, 1, 2]
        },
        "config": {
            "type": "object",
            "additionalProperties": false,
            "required": ["options", "minOptions", "maxOptions", "allowAbstention"],
            "properties": {
                "options": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                        "type": "string"
                    }
                },
                "minOptions": {
                    "type": "integer",
                    "minimum": 1
                },
                "maxOptions": {
                    "type": "integer",
                    "minimum": {
                        "$data": "1/minOptions"
                    },
                    "maximum": {
                        "$data": "1/options/length"
                    }
                },
                "acceptanceCriteria": {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                        "minTurnout": {
                            "$ref": "#/definitions/weightedUnweighted"
                        }
                    }
                },
                "winnerCriteria": {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                        "minSupport": {
                            "type": "object",
                            "oneOf": [
                                {
                                    "propertyNames": {
                                        "enum": {
                                            "$data": "3/options"
                                        }
                                    }
                                },
                                {
                                    "propertyNames": {
                                        "const": "*"
                                    }
                                }
                            ],
                            "patternProperties": {
                                ".*": {
                                    "$ref": "#/definitions/weightedUnweighted"
                                }
                            }
                        }
                    }
                },
                "computeResultsAgainst": {
                    "enum": ["ALL_ELIGIBLE_VOTERS", "PARTICIPANTS_ONLY"]
                },
                "allowAbstention": {
                    "type": "boolean"
                }
            }
        }
    },
    "oneOf": [
        {
            "$ref": "#/definitions/type0"
        },
        {
            "$ref": "#/definitions/type1"
        },
        {
            "$ref": "#/definitions/type2"
        }
    ]
}
