{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "https://joystream.org/AddClassSchema.schema.json",
  "title": "AddClassSchema",
  "description": "JSON schema to describe a new schema for a certain class in Joystream network",
  "type": "object",
  "additionalProperties": false,
  "required": ["className", "newProperties"],
  "properties": {
    "className": { "type": "string" },
    "existingProperties": {
      "type": "array",
      "uniqueItems": true,
      "items": { "$ref": "#/definitions/PropertyInSchemIndex" }
    },
    "newProperties": {
      "type": "array",
      "uniqueItems": true,
      "items": { "$ref": "#/definitions/Property" }
    }
  },
  "definitions": {
    "ClassId": {
      "type": "integer",
      "minimum": 1
    },
    "PropertyInSchemIndex": {
      "type": "integer",
      "minimum": 0
    },
    "DefaultBoolean": {
      "type": "boolean",
      "default": false
    },
    "Property": {
      "type": "object",
      "additionalProperties": false,
      "required": ["name", "property_type"],
      "properties": {
        "property_type": {
          "oneOf": [{ "$ref": "#/definitions/SinglePropertyVariant" }, { "$ref": "#/definitions/VecPropertyVariant" }]
        },
        "name": { "$ref": "#/definitions/PropertyName" },
        "description": { "$ref": "#/definitions/PropertyDescription" },
        "required": { "$ref": "#/definitions/DefaultBoolean" },
        "unique": { "$ref": "#/definitions/DefaultBoolean" },
        "locking_policy": { "$ref": "#/definitions/LockingPolicy" }
      }
    },
    "PropertyName": {
      "type": "string",
      "minLength": 1,
      "maxLength": 49
    },
    "PropertyDescription": {
      "type": "string",
      "minLength": 1,
      "maxLength": 500,
      "default": ""
    },
    "SinglePropertyType": {
      "oneOf": [
        { "$ref": "#/definitions/PrimitiveProperty", "description": "Primitive property (bool/integer)" },
        { "$ref": "#/definitions/TextProperty" },
        { "$ref": "#/definitions/HashProperty" },
        { "$ref": "#/definitions/ReferenceProperty" }
      ]
    },
    "SinglePropertyVariant": {
      "type": "object",
      "additionalProperties": false,
      "required": ["Single"],
      "properties": {
        "Single": { "$ref": "#/definitions/SinglePropertyType" }
      }
    },
    "VecPropertyType": {
      "type": "object",
      "additionalProperties": false,
      "required": ["vec_type", "max_length"],
      "properties": {
        "vec_type": { "$ref": "#/definitions/SinglePropertyType" },
        "max_length": { "$ref": "#/definitions/MaxVecItems" }
      }
    },
    "VecPropertyVariant": {
      "type": "object",
      "additionalProperties": false,
      "required": ["Vector"],
      "properties": {
        "Vector": { "$ref": "#/definitions/VecPropertyType" }
      }
    },
    "PrimitiveProperty": {
      "type": "string",
      "enum": ["Bool", "Uint16", "Uint32", "Uint64", "Int16", "Int32", "Int64"]
    },
    "TextProperty": {
      "type": "object",
      "additionalProperties": false,
      "required": ["Text"],
      "properties": {
        "Text": { "$ref": "#/definitions/MaxTextLength" }
      }
    },
    "HashProperty": {
      "type": "object",
      "additionalProperties": false,
      "required": ["Hash"],
      "properties": {
        "Hash": { "$ref": "#/definitions/MaxTextLength" }
      }
    },
    "MaxTextLength": {
      "type": "integer",
      "minimum": 1,
      "maximum": 65535
    },
    "MaxVecItems": {
      "type": "integer",
      "minimum": 1,
      "maximum": 65535
    },
    "ReferenceProperty": {
      "type": "object",
      "additionalProperties": false,
      "required": ["Reference"],
      "properties": {
        "Reference": {
          "type": "object",
          "additionalProperties": false,
          "required": ["className"],
          "properties": {
            "className": {
              "type": "string",
              "description": "Referenced class name"
            },
            "sameOwner": {
              "$ref": "#/definitions/DefaultBoolean",
              "description": "Whether same owner (controller) is required"
            }
          }
        }
      }
    },
    "LockingPolicy": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "is_locked_from_maintainer": { "$ref": "#/definitions/DefaultBoolean" },
        "is_locked_from_controller": { "$ref": "#/definitions/DefaultBoolean" }
      }
    }
  }
}
