"$schema": "http://json-schema.org/draft-04/schema#"
type: "object"
properties:
    homeserver:
        type: "object"
        properties:
            url:
                type: "string"
            media_url:
                type: "string"
            domain:
                type: "string"
            dropMatrixMessagesAfterSecs:
                type: "integer"
        required: ["url", "domain"]
    ircService:
        type: "object"
        properties:
            databaseUri:
                type: "string"
            metrics:
                type: "object"
                properties:
                    enabled:
                        type: "boolean"
            statsd:
                type: "object"
                properties:
                    hostname:
                        type: "string"
                    port:
                        type: "integer"
                    jobName:
                        type: "string"
                required: ["hostname", "port"]
            ident:
                type: "object"
                properties:
                    enabled:
                        type: "boolean"
                    port:
                        type: "integer"
                    address:
                        type: "string"
                required: ["enabled"]
            debugApi:
                type: "object"
                properties:
                    enabled:
                        type: "boolean"
                    port:
                        type: "integer"
                required: ["enabled", "port"]
            logging:
                type: "object"
                properties:
                    level:
                        type: "string"
                        enum: ["error","warn","info","debug"]
                    logfile:
                        type: "string"
                    errfile:
                        type: "string"
                    toConsole:
                        type: "boolean"
                    maxFileSizeBytes:
                        type: "integer"
                    maxFiles:
                        type: "integer"
            provisioning:
                type: "object"
                properties:
                    enabled:
                        type: "boolean"
                    requestTimeoutSeconds:
                        type: "number"
            passwordEncryptionKeyPath:
                type: "string"
            servers:
                type: "object"
                # all properties must follow the following
                additionalProperties:
                    type: "object"
                    properties:
                        port:
                            type: "integer"
                        additionalAddresses:
                            type: "array"
                            items:
                                type: "string"
                        ssl:
                            type: "boolean"
                        sslselfsign:
                            type: "boolean"
                        password:
                            type: "string"
                        sendConnectionMessages:
                            type: "boolean"
                        name:
                            type: "string"
                        description:
                            type: "string"
                        networkId:
                            type: "string"
                            pattern: "^[a-zA-Z0-9]+$"
                        icon:
                            type: "string"
                        quitDebounce:
                            type: "object"
                            properties:
                                enabled:
                                    type: "boolean"
                                quitsPerSecond:
                                    type: "number"
                                delayMinMs:
                                    type: "integer"
                                    minimum: 0
                                    exclusiveMinimum: true
                                delayMaxMs:
                                    type: "integer"
                                    minimum: 0
                                    exclusiveMinimum: true
                        modePowerMap:
                            type: "object"
                            patternProperties:
                                # Single character modes mapped to positive power levels
                                "^[a-zA-Z]$":
                                    type: number
                                    minimum: 0
                        botConfig:
                            type: "object"
                            properties:
                                enabled:
                                    type: "boolean"
                                nick:
                                    type: "string"
                                password:
                                    type: "string"
                                joinChannelsIfNoUsers:
                                    type: "boolean"
                        privateMessages:
                            type: "object"
                            properties:
                                enabled:
                                    type: "boolean"
                                exclude:
                                    type: "array"
                                    items:
                                        type: "string"
                                federate:
                                    type: "boolean"
                        membershipLists:
                            type: "object"
                            properties:
                                enabled:
                                    type: "boolean"
                                floodDelayMs:
                                    type: "integer"
                                global:
                                    type: "object"
                                    properties:
                                        ircToMatrix:
                                            type: "object"
                                            properties:
                                                initial:
                                                    type: "boolean"
                                                incremental:
                                                    type: "boolean"
                                        matrixToIrc:
                                            type: "object"
                                            properties:
                                                initial:
                                                    type: "boolean"
                                                incremental:
                                                    type: "boolean"
                                    additionalProperties: false
                                rooms:
                                    type: "array"
                                    items:
                                        type: "object"
                                        properties:
                                            room:
                                                type: "string"
                                                pattern: "^!+.*$"
                                            matrixToIrc:
                                                type: "object"
                                                properties:
                                                    initial:
                                                        type: "boolean"
                                                    incremental:
                                                        type: "boolean"
                                        additionalProperties: false
                                channels:
                                    type: "array"
                                    items:
                                        type: "object"
                                        properties:
                                            channel:
                                                type: "string"
                                                pattern: "^#+.*$"
                                            ircToMatrix:
                                                type: "object"
                                                properties:
                                                    initial:
                                                        type: "boolean"
                                                    incremental:
                                                        type: "boolean"
                                        additionalProperties: false
                        dynamicChannels:
                            type: "object"
                            properties:
                                enabled:
                                    type: "boolean"
                                published:
                                    type: "boolean"
                                createAlias:
                                    type: "boolean"
                                joinRule:
                                    type: "string"
                                    enum: ["invite", "public"]
                                federate:
                                    type: "boolean"
                                aliasTemplate:
                                    type: "string"
                                    pattern: "^#.*\\$CHANNEL"
                                whitelist:
                                    type: "array"
                                    items:
                                        type: "string"
                                        pattern: "^@.*"
                                exclude:
                                    type: "array"
                                    items:
                                        type: "string"
                        mappings:
                            type: "object"
                            patternProperties:
                                # must start with a #
                                "^#+.*$":
                                    type: "array"
                                    items:
                                        type: "string"
                                    minItems: 1
                                    uniqueItems: true
                            additionalProperties: false
                        matrixClients:
                            type: "object"
                            properties:
                                userTemplate:
                                    type: "string"
                                    pattern: "^@.*\\$NICK"
                                displayName:
                                    type: "string"
                                    pattern: "\\$NICK"
                        ircClients:
                            type: "object"
                            properties:
                                nickTemplate:
                                    type: "string"
                                    pattern: "\\$USERID|\\$LOCALPART|\\$DISPLAY"
                                maxClients:
                                    type: "integer"
                                idleTimeout:
                                    type: "integer"
                                    minimum: 0
                                reconnectIntervalMs:
                                    type: "integer"
                                    minimum: 0
                                allowNickChanges:
                                    type: "boolean"
                                ipv6:
                                    type: "object"
                                    properties:
                                        prefix:
                                            type: "string"
                                            pattern: "[ABCDEFabcdef0123456789:]+"
                                        only:
                                            type: "boolean"
                                lineLimit:
                                    type: "integer"
                                userModes:
                                    type: "string"
        required: ["databaseUri", "servers"]
