{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "$id": "https://developer.actyx.com/schemas/node-settings.schema.json",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "swarm": {
      "$ref": "#/definitions/Swarm"
    },
    "licensing": {
      "$ref": "#/definitions/Licensing"
    },
    "admin": {
      "$ref": "#/definitions/Admin"
    },
    "api": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "events": {
          "$ref": "#/definitions/API/Events"
        }
      }
    },
    "eventRouting": {
      "$ref": "#/definitions/EventRouting"
    }
  },
  "definitions": {
    "Basic": {
      "Key": {
        "type": "string",
        "minLength": 44,
        "maxLength": 44
      },
      "NonEmptyString": {
        "type": "string",
        "minLength": 1
      },
      "Topic": {
        "type": "string",
        "minLength": 1,
        "maxLength": 60
      },
      "MultiAddr": {
        "type": "string",
        "format": "multiaddr-without-peer-id"
      },
      "MultiAddrWithPeerId": {
        "type": "string",
        "format": "multiaddr-with-peer-id"
      },
      "NodeLicenseKey": {
        "type": "string",
        "minLength": 64
      },
      "AppLicenseKey": {
        "type": "string",
        "minLength": 100
      },
      "UserKey": {
        "type": "string",
        "minLength": 45,
        "maxLength": 45
      }
    },
    "Composite": {
      "LogLevel": {
        "type": "string",
        "pattern": "^(ERROR|WARN|INFO|DEBUG|[a-z0-9_:,=]+)$",
        "default": "INFO"
      },
      "NodeLicense": {
        "oneOf": [
          {
            "$ref": "#/definitions/Basic/NodeLicenseKey"
          },
          {
            "type": "string",
            "const": "development"
          }
        ]
      },
      "AppLicense": {
        "oneOf": [
          {
            "$ref": "#/definitions/Basic/AppLicenseKey"
          },
          {
            "type": "string",
            "const": "testing"
          }
        ]
      },
      "StreamSize": {
        "type": "string",
        "pattern": "^([1-9][0-9]*)(B|kB|MB|GB|KiB|MiB|GiB)$"
      },
      "StreamAge": {
        "type": "string",
        "pattern": "^[1-9][0-9]+(s|m|h|d|w)$"
      }
    },
    "Swarm": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "swarmKey": {
          "$ref": "#/definitions/Basic/Key",
          "default": "MDAwMDAwMDAxMTExMTExMTIyMjIyMjIyMzMzMzMzMzM="
        },
        "topic": {
          "$ref": "#/definitions/Basic/Topic",
          "default": "default-topic"
        },
        "initialPeers": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Basic/MultiAddrWithPeerId"
          },
          "default": [],
          "uniqueItems": true,
          "description": "Addresses of peers to initially connect to. These must be multiaddresses containing a peer id. E.g. /dns4/demo-bootstrap.actyx.net/tcp/4001/p2p/QmUD1mA3Y8qSQB34HmgSNcxDss72UHW2kzQy7RdVstN2hH"
        },
        "announceAddresses": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Basic/MultiAddr"
          },
          "minItems": 0,
          "uniqueItems": true,
          "default": [],
          "description": "Manually configured addresses to announce. These must be multiaddresses without peer id, e.g. /ip4/1.2.3.4/tcp/4001"
        },
        "blockCacheCount": {
          "type": "integer",
          "minimum": 0,
          "default": 131072,
          "description": "Maximum number of non-pinned blocks to cache"
        },
        "blockCacheSize": {
          "type": "integer",
          "minimum": 0,
          "default": 1073741824,
          "description": "Maximum number of bytes of non-pinned blocks to cache"
        },
        "blockGcInterval": {
          "type": "integer",
          "minimum": 30,
          "default": 300,
          "description": "GC interval for the block store, in seconds"
        },
        "metricsInterval": {
          "type": "integer",
          "minimum": 0,
          "default": 1800,
          "description": "Metrics event emission interval, in seconds"
        },
        "pingTimeout": {
          "type": "integer",
          "minimum": 0,
          "default": 5,
          "description": "Timeout for one swarm-internal ping response"
        },
        "bitswapTimeout": {
          "type": "integer",
          "minimum": 0,
          "default": 15,
          "description": "Timeout for one swarm-internal data block response"
        },
        "mdns": {
          "type": "boolean",
          "default": true,
          "description": "Enable mDNS discovery of peers within the same IP broadcast domain"
        },
        "branchCacheSize": {
          "type": "integer",
          "default": 67108864,
          "description": "Maximum number of index bytes cached in memory"
        },
        "gossipInterval": {
          "type": "integer",
          "default": 10,
          "description": "Interval at which the node sends its known stream links and offsets to all peers"
        },
        "detectionCyclesLowLatency": {
          "type": "number",
          "default": 2,
          "description": "multiple of the gossipInterval used for determining low-latency stream replication"
        },
        "detectionCyclesHighLatency": {
          "type": "number",
          "default": 5,
          "description": "multiple of the gossipInterval used for determining high-latency but still working stream replication"
        }
      }
    },
    "Admin": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "displayName": {
          "$ref": "#/definitions/Basic/NonEmptyString",
          "default": "Default Node"
        },
        "logLevels": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "node": {
              "$ref": "#/definitions/Composite/LogLevel"
            }
          }
        },
        "authorizedUsers": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Basic/UserKey"
          },
          "default": [],
          "uniqueItems": true,
          "description": "Public keys of the users allowed to connect to the node."
        }
      }
    },
    "Licensing": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "node": {
          "$ref": "#/definitions/Composite/NodeLicense",
          "default": "development"
        },
        "apps": {
          "type": "object",
          "propertyNames": {
            "pattern": "^(\\d|\\w|-|_)+(\\.(\\d|\\w|-|_)+)*$"
          },
          "additionalProperties": {
            "$ref": "#/definitions/Composite/AppLicense"
          },
          "description": "Key-value pairs where the key is an app's ID.",
          "default": {}
        }
      }
    },
    "API": {
      "Events": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "readOnly": {
            "type": "boolean",
            "default": false
          },
          "_internal": {
            "type": "object",
            "additionalProperties": true
          }
        }
      }
    },
    "EventRouting": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "streams": {
          "type": "object",
          "propertyNames": {
            "pattern": "^[a-zA-Z0-9_-]+$"
          },
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "maxEvents": {
                "type": "integer",
                "description": "The number of most recent events to keep.",
                "minimum": 0,
                "default": 0
              },
              "maxSize": {
                "$ref": "#/definitions/Composite/StreamSize",
                "description": "Streams will be pruned when occupying storage beyond the provided limit. Can be B (bytes), kB (Kilobytes), KiB (Kibibytes), MB (Megabytes), (MiB) MebiBytes, GB (Gigabytes) or GiB (Gibibytes). If no unit is provided, the unit is considered to be bytes.",
                "default": "0"
              },
              "maxAge": {
                "$ref": "#/definitions/Composite/StreamAge",
                "description": "The maximum age for stream events. Can be s (seconds), m (minutes), h (hours), d (days) or w (weeks).",
                "default": null
              }
            }
          },
          "default": {}
        },
        "routes": {
          "type": "array",
          "items": {
            "additionalProperties": false,
            "properties": {
              "from": {
                "type": "string",
                "pattern": "^('([^']|'')+')|(\"([^\"]|\"\")+\") *([|&] *('([^']|'')+')|(\"([^\"]|\"\")+\"))*$"
              },
              "into": {
                "type": "string",
                "pattern": "^[a-zA-Z0-9_-]+$"
              }
            },
            "required": [
              "from",
              "into"
            ]
          },
          "default": []
        }
      }
    }
  }
}
