{
  "$id": "http://asl-validator.cloud/choice.json#",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "ChoiceRules": {
      "Boolean": {
        "And": {
          "type": "object",
          "required": ["And"],
          "properties": {
            "And": {
              "type": "array",
              "minItems": 1,
              "items": {
                "oneOf": [
                  {
                    "$ref": "#/definitions/ChoiceRules/Boolean/_BooleanExpression"
                  },
                  {
                    "$ref": "#/definitions/ChoiceRules/DataTest/_DataTestExpression"
                  }
                ]
              }
            }
          }
        },
        "Or": {
          "type": "object",
          "required": ["Or"],
          "properties": {
            "Or": {
              "type": "array",
              "minItems": 1,
              "items": {
                "oneOf": [
                  {
                    "$ref": "#/definitions/ChoiceRules/Boolean/_BooleanExpression"
                  },
                  {
                    "$ref": "#/definitions/ChoiceRules/DataTest/_DataTestExpression"
                  }
                ]
              }
            }
          }
        },
        "Not": {
          "type": "object",
          "required": ["Not"],
          "properties": {
            "Not": {
              "oneOf": [
                {
                  "$ref": "#/definitions/ChoiceRules/Boolean/_BooleanExpression"
                },
                {
                  "$ref": "#/definitions/ChoiceRules/DataTest/_DataTestExpression"
                }
              ]
            }
          }
        },
        "_BooleanExpression": {
          "$comment": "A nested BooleanExpression MUST NOT have a Next or Assign",
          "type": "object",
          "oneOf": [
            {
              "$ref": "#/definitions/ChoiceRules/Boolean/And"
            },
            {
              "$ref": "#/definitions/ChoiceRules/Boolean/Or"
            },
            {
              "$ref": "#/definitions/ChoiceRules/Boolean/Not"
            }
          ]
        },
        "BooleanExpression": {
          "$comment": "Top level BooleanExpression MUST have a Next and MAY have an Assign",
          "type": "object",
          "required": ["Next"],
          "properties": {
            "Assign": {
              "$ref": "paths.json#/definitions/assign"
            },
            "Next": {
              "type": "string"
            }
          },
          "oneOf": [
            {
              "$ref": "#/definitions/ChoiceRules/Boolean/And"
            },
            {
              "$ref": "#/definitions/ChoiceRules/Boolean/Or"
            },
            {
              "$ref": "#/definitions/ChoiceRules/Boolean/Not"
            }
          ]
        }
      },
      "DataTest": {
        "IsNull": {
          "type": "object",
          "required": ["IsNull"],
          "properties": {
            "IsNull": {
              "type": "boolean"
            }
          }
        },
        "IsPresent": {
          "type": "object",
          "required": ["IsPresent"],
          "properties": {
            "IsPresent": {
              "type": "boolean"
            }
          }
        },
        "BooleanEquals": {
          "type": "object",
          "required": ["BooleanEquals"],
          "properties": {
            "BooleanEquals": {
              "type": "boolean"
            }
          }
        },
        "BooleanEqualsPath": {
          "type": "object",
          "required": ["BooleanEqualsPath"],
          "properties": {
            "BooleanEqualsPath": {
              "$ref": "paths.json#/definitions/asl_ref_path"
            }
          }
        },
        "IsBoolean": {
          "type": "object",
          "required": ["IsBoolean"],
          "properties": {
            "IsBoolean": {
              "type": "boolean"
            }
          }
        },
        "NumericEquals": {
          "type": "object",
          "required": ["NumericEquals"],
          "properties": {
            "NumericEquals": {
              "type": "number"
            }
          }
        },
        "NumericEqualsPath": {
          "type": "object",
          "required": ["NumericEqualsPath"],
          "properties": {
            "NumericEqualsPath": {
              "$ref": "paths.json#/definitions/asl_ref_path"
            }
          }
        },
        "NumericGreaterThan": {
          "type": "object",
          "required": ["NumericGreaterThan"],
          "properties": {
            "NumericGreaterThan": {
              "type": "number"
            }
          }
        },
        "NumericGreaterThanPath": {
          "type": "object",
          "required": ["NumericGreaterThanPath"],
          "properties": {
            "NumericGreaterThanPath": {
              "$ref": "paths.json#/definitions/asl_ref_path"
            }
          }
        },
        "NumericGreaterThanEquals": {
          "type": "object",
          "required": ["NumericGreaterThanEquals"],
          "properties": {
            "NumericGreaterThanEquals": {
              "type": "number"
            }
          }
        },
        "NumericGreaterThanEqualsPath": {
          "type": "object",
          "required": ["NumericGreaterThanEqualsPath"],
          "properties": {
            "NumericGreaterThanEqualsPath": {
              "$ref": "paths.json#/definitions/asl_ref_path"
            }
          }
        },
        "NumericLessThan": {
          "type": "object",
          "required": ["NumericLessThan"],
          "properties": {
            "NumericLessThan": {
              "type": "number"
            }
          }
        },
        "NumericLessThanPath": {
          "type": "object",
          "required": ["NumericLessThanPath"],
          "properties": {
            "NumericLessThanPath": {
              "$ref": "paths.json#/definitions/asl_ref_path"
            }
          }
        },
        "NumericLessThanEquals": {
          "type": "object",
          "required": ["NumericLessThanEquals"],
          "properties": {
            "NumericLessThanEquals": {
              "type": "number"
            }
          }
        },
        "NumericLessThanEqualsPath": {
          "type": "object",
          "required": ["NumericLessThanEqualsPath"],
          "properties": {
            "NumericLessThanEqualsPath": {
              "$ref": "paths.json#/definitions/asl_ref_path"
            }
          }
        },
        "IsNumeric": {
          "type": "object",
          "required": ["IsNumeric"],
          "properties": {
            "IsNumeric": {
              "type": "boolean"
            }
          }
        },
        "StringEquals": {
          "type": "object",
          "required": ["StringEquals"],
          "properties": {
            "StringEquals": {
              "type": "string"
            }
          }
        },
        "StringEqualsPath": {
          "type": "object",
          "required": ["StringEqualsPath"],
          "properties": {
            "StringEqualsPath": {
              "$ref": "paths.json#/definitions/asl_ref_path"
            }
          }
        },
        "StringGreaterThan": {
          "type": "object",
          "required": ["StringGreaterThan"],
          "properties": {
            "StringGreaterThan": {
              "type": "string"
            }
          }
        },
        "StringGreaterThanPath": {
          "type": "object",
          "required": ["StringGreaterThanPath"],
          "properties": {
            "StringGreaterThanPath": {
              "$ref": "paths.json#/definitions/asl_ref_path"
            }
          }
        },
        "StringGreaterThanEquals": {
          "type": "object",
          "required": ["StringGreaterThanEquals"],
          "properties": {
            "StringGreaterThanEquals": {
              "type": "string"
            }
          }
        },
        "StringGreaterThanEqualsPath": {
          "type": "object",
          "required": ["StringGreaterThanEqualsPath"],
          "properties": {
            "StringGreaterThanEqualsPath": {
              "$ref": "paths.json#/definitions/asl_ref_path"
            }
          }
        },
        "StringLessThan": {
          "type": "object",
          "required": ["StringLessThan"],
          "properties": {
            "StringLessThan": {
              "type": "string"
            }
          }
        },
        "StringLessThanPath": {
          "type": "object",
          "required": ["StringLessThanPath"],
          "properties": {
            "StringLessThanPath": {
              "$ref": "paths.json#/definitions/asl_ref_path"
            }
          }
        },
        "StringLessThanEquals": {
          "type": "object",
          "required": ["StringLessThanEquals"],
          "properties": {
            "StringLessThanEquals": {
              "type": "string"
            }
          }
        },
        "StringLessThanEqualsPath": {
          "type": "object",
          "required": ["StringLessThanEqualsPath"],
          "properties": {
            "StringLessThanEqualsPath": {
              "$ref": "paths.json#/definitions/asl_ref_path"
            }
          }
        },
        "StringMatches": {
          "type": "object",
          "required": ["StringMatches"],
          "properties": {
            "StringMatches": {
              "type": "string"
            }
          }
        },
        "IsString": {
          "type": "object",
          "required": ["IsString"],
          "properties": {
            "IsString": {
              "type": "boolean"
            }
          }
        },
        "TimestampEquals": {
          "type": "object",
          "required": ["TimestampEquals"],
          "properties": {
            "TimestampEquals": {
              "type": "string"
            }
          }
        },
        "TimestampEqualsPath": {
          "type": "object",
          "required": ["TimestampEqualsPath"],
          "properties": {
            "TimestampEqualsPath": {
              "$ref": "paths.json#/definitions/asl_ref_path"
            }
          }
        },
        "TimestampGreaterThan": {
          "type": "object",
          "required": ["TimestampGreaterThan"],
          "properties": {
            "TimestampGreaterThan": {
              "type": "string"
            }
          }
        },
        "TimestampGreaterThanPath": {
          "type": "object",
          "required": ["TimestampGreaterThanPath"],
          "properties": {
            "TimestampGreaterThanPath": {
              "$ref": "paths.json#/definitions/asl_ref_path"
            }
          }
        },
        "TimestampGreaterThanEquals": {
          "type": "object",
          "required": ["TimestampGreaterThanEquals"],
          "properties": {
            "TimestampGreaterThanEquals": {
              "type": "string"
            }
          }
        },
        "TimestampGreaterThanEqualsPath": {
          "type": "object",
          "required": ["TimestampGreaterThanEqualsPath"],
          "properties": {
            "TimestampGreaterThanEqualsPath": {
              "$ref": "paths.json#/definitions/asl_ref_path"
            }
          }
        },
        "TimestampLessThan": {
          "type": "object",
          "required": ["TimestampLessThan"],
          "properties": {
            "TimestampLessThan": {
              "type": "string"
            }
          }
        },
        "TimestampLessThanPath": {
          "type": "object",
          "required": ["TimestampLessThanPath"],
          "properties": {
            "TimestampLessThanPath": {
              "$ref": "paths.json#/definitions/asl_ref_path"
            }
          }
        },
        "TimestampLessThanEquals": {
          "type": "object",
          "required": ["TimestampLessThanEquals"],
          "properties": {
            "TimestampLessThanEquals": {
              "type": "string"
            }
          }
        },
        "TimestampLessThanEqualsPath": {
          "type": "object",
          "required": ["TimestampLessThanEqualsPath"],
          "properties": {
            "TimestampLessThanEqualsPath": {
              "$ref": "paths.json#/definitions/asl_ref_path"
            }
          }
        },
        "IsTimestamp": {
          "type": "object",
          "required": ["IsTimestamp"],
          "properties": {
            "IsTimestamp": {
              "type": "boolean"
            }
          }
        },
        "_DataTestExpression": {
          "$comment": "Nested DataTestExpression MUST NOT have a Next and MAY have an Assign",
          "type": "object",
          "required": ["Variable"],
          "properties": {
            "Variable": {
              "$ref": "paths.json#/definitions/asl_ref_path"
            }
          },
          "oneOf": [
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/IsNull"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/IsPresent"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/BooleanEquals"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/BooleanEqualsPath"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/IsBoolean"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/NumericEquals"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/NumericEqualsPath"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/NumericGreaterThan"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/NumericGreaterThanPath"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/NumericGreaterThanEquals"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/NumericGreaterThanEqualsPath"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/NumericLessThan"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/NumericLessThanPath"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/NumericLessThanEquals"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/NumericLessThanEqualsPath"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/IsNumeric"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/StringEquals"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/StringEqualsPath"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/StringGreaterThan"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/StringGreaterThanPath"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/StringGreaterThanEquals"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/StringGreaterThanEqualsPath"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/StringLessThan"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/StringLessThanPath"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/StringLessThanEquals"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/StringLessThanEqualsPath"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/StringMatches"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/IsString"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/TimestampEquals"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/TimestampEqualsPath"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/TimestampGreaterThan"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/TimestampGreaterThanPath"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/TimestampGreaterThanEquals"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/TimestampGreaterThanEqualsPath"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/TimestampLessThan"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/TimestampLessThanPath"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/TimestampLessThanEquals"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/TimestampLessThanEqualsPath"
            },
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/IsTimestamp"
            }
          ]
        },
        "DataTestExpression": {
          "$comment": "Top level DataTestExpression MUST have a Next and MAY have an Assign",
          "type": "object",
          "properties": {
            "Assign": {
              "$ref": "paths.json#/definitions/assign"
            },
            "Next": {
              "type": "string"
            }
          },
          "required": ["Next"],
          "allOf": [
            {
              "$ref": "#/definitions/ChoiceRules/DataTest/_DataTestExpression"
            }
          ]
        }
      }
    },
    "Type": {
      "type": "string",
      "enum": ["Choice"]
    },
    "Default": {
      "type": "string"
    }
  },
  "oneOf": [
    {
      "type": "object",
      "properties": {
        "Type": {
          "$ref": "#/definitions/Type"
        },
        "End": {
          "$ref": "common.json#/definitions/End"
        },
        "Comment": {
          "$ref": "common.json#/definitions/Comment"
        },
        "Default": {
          "$ref": "#/definitions/Default"
        },
        "Assign": {
          "$ref": "paths.json#/definitions/assign"
        },
        "Choices": {
          "type": "array",
          "minItems": 1,
          "items": {
            "oneOf": [
              {
                "$ref": "#/definitions/ChoiceRules/Boolean/BooleanExpression"
              },
              {
                "$ref": "#/definitions/ChoiceRules/DataTest/DataTestExpression"
              }
            ]
          }
        },
        "OutputPath": {
          "$ref": "paths.json#/definitions/asl_path"
        },
        "InputPath": {
          "$ref": "paths.json#/definitions/asl_path"
        },
        "QueryLanguage": {
          "$ref": "paths.json#/definitions/queryLanguage"
        }
      },
      "required": ["Choices", "QueryLanguage", "Type"],
      "additionalProperties": false
    },
    {
      "type": "object",
      "properties": {
        "Type": {
          "$ref": "#/definitions/Type"
        },
        "End": {
          "$ref": "common.json#/definitions/End"
        },
        "Comment": {
          "$ref": "common.json#/definitions/Comment"
        },
        "Default": {
          "$ref": "#/definitions/Default"
        },
        "Assign": {
          "$ref": "jsonata.json#/definitions/assign"
        },
        "Choices": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "object",
            "required": ["Condition", "Next"],
            "properties": {
              "Assign": {
                "$ref": "jsonata.json#/definitions/assign"
              },
              "Condition": {
                "$ref": "jsonata.json#/definitions/condition"
              },
              "Next": {
                "type": "string"
              }
            }
          }
        },
        "Output": {
          "$ref": "jsonata.json#/definitions/output"
        },
        "QueryLanguage": {
          "$ref": "jsonata.json#/definitions/queryLanguage"
        }
      },
      "required": ["Choices", "QueryLanguage", "Type"],
      "additionalProperties": false
    }
  ]
}
