{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Configuration",
  "type": "object",
  "properties": {
    "caches": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/definitions/Cache"
      },
      "default": {}
    },
    "connections": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/definitions/ConnectionConfig"
      }
    },
    "consumer": {
      "$ref": "#/definitions/ConsumerConfig"
    },
    "controlPlane": {
      "anyOf": [
        {
          "$ref": "#/definitions/ControlPlaneConfig"
        },
        {
          "type": "null"
        }
      ]
    },
    "processor": {
      "$ref": "#/definitions/ProcessorModeConfig"
    },
    "producer": {
      "$ref": "#/definitions/ProducerConfig"
    }
  },
  "required": [
    "connections",
    "consumer",
    "producer",
    "processor"
  ],
  "definitions": {
    "Cache": {
      "oneOf": [
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "const": "in-memory"
            }
          },
          "required": [
            "type"
          ]
        },
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "const": "mongodb"
            }
          },
          "allOf": [
            {
              "$ref": "#/definitions/MongodbCacheConfig"
            }
          ],
          "required": [
            "type"
          ]
        },
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "const": "farm-data"
            }
          },
          "allOf": [
            {
              "$ref": "#/definitions/FarmDataConfig"
            }
          ],
          "required": [
            "type"
          ]
        },
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "const": "http-rest"
            }
          },
          "allOf": [
            {
              "$ref": "#/definitions/HttpRestConfig"
            }
          ],
          "required": [
            "type"
          ]
        }
      ]
    },
    "ConnectionConfig": {
      "oneOf": [
        {
          "type": "object",
          "properties": {
            "config": {
              "$ref": "#/definitions/KafkaConnectionConfig"
            },
            "type": {
              "type": "string",
              "const": "kafka"
            }
          },
          "required": [
            "type",
            "config"
          ]
        },
        {
          "type": "object",
          "properties": {
            "config": {
              "$ref": "#/definitions/MongodbConnectionConfig"
            },
            "type": {
              "type": "string",
              "const": "mongodb"
            }
          },
          "required": [
            "type",
            "config"
          ]
        }
      ]
    },
    "ConsumerConfig": {
      "oneOf": [
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "const": "kafka"
            }
          },
          "allOf": [
            {
              "$ref": "#/definitions/KafkaConsumerConfig"
            }
          ],
          "required": [
            "type"
          ]
        }
      ]
    },
    "ControlPlaneConfig": {
      "type": "object",
      "properties": {
        "feedbackInterval": {
          "description": "Interval in milliseconds that must elapse between two feedback events sent to Control Plane Operator.\nIt defaults to `3000` ms when not provided during deserialization.",
          "type": "integer",
          "format": "uint64",
          "default": 3000,
          "minimum": 0
        },
        "grpcAddress": {
          "description": "Address to the gRPC server that should receive service feedback events",
          "type": "string",
          "examples": [
            "http://control-plane-operator:50052"
          ]
        },
        "onCreate": {
          "description": "Desired initial state of the Service, to be included in the registration request with the Control Plane.\nIf not provided, the service will start in `Pause` state.",
          "anyOf": [
            {
              "$ref": "#/definitions/InitialState"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "resumeAfterMs": {
          "description": "The number of milliseconds to wait before running the processing logic\nwhen connection with control plane operator failed\nand no desired fast data state was ever received.",
          "type": [
            "integer",
            "null"
          ],
          "format": "uint64",
          "default": null,
          "minimum": 0
        }
      },
      "required": [
        "grpcAddress"
      ]
    },
    "FarmDataConfig": {
      "type": "object",
      "properties": {
        "head": {
          "description": "The name of the aggregation head node",
          "type": "string"
        },
        "http2": {
          "description": "Whether to use HTTP/2 prior knowledge",
          "type": "boolean",
          "default": false
        },
        "url": {
          "description": "The base URL of the FarmData service.",
          "type": "string",
          "format": "uri"
        }
      },
      "required": [
        "url",
        "head"
      ]
    },
    "HttpRestConfig": {
      "type": "object",
      "properties": {
        "get": {
          "description": "Cache GET endpoint configuration",
          "anyOf": [
            {
              "$ref": "#/definitions/RestEndpointConfig"
            },
            {
              "type": "null"
            }
          ]
        },
        "http2": {
          "description": "Whether to use HTTP/2 prior knowledge",
          "type": "boolean",
          "default": false
        },
        "url": {
          "description": "The common base URL for the REST endpoints.",
          "type": "string",
          "format": "uri"
        }
      },
      "required": [
        "url"
      ]
    },
    "InitialState": {
      "description": "Enum to map the initial state of the service when registering to Control Plane,\naccording to the value defined in the configuration file.\n\nThis state should be used to be mapped to the Piper's ExecState.",
      "type": "string",
      "enum": [
        "pause",
        "resume"
      ]
    },
    "KafkaConnectionConfig": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/definitions/Secret"
      }
    },
    "KafkaConsumerConfig": {
      "type": "object",
      "properties": {
        "commitIntervalMs": {
          "description": "number of milliseconds between one commit and another",
          "type": "integer",
          "format": "uint64",
          "default": 500,
          "minimum": 0
        },
        "config": {
          "description": "librdkafka Kafka consumer configuration properties\nlibrdkafka Kafka consumer configuration properties. Do not include here Kafka configurations\nabout the Kafka instance and/or connection, as it will be overrided by the selected connection",
          "type": "object",
          "additionalProperties": {
            "$ref": "#/definitions/Secret"
          },
          "default": {}
        },
        "connectionName": {
          "description": "connection name to use from the connections map (must be type kafka)\n\nThis property is required from version 0.6.0 onwards.",
          "type": "string"
        },
        "topic": {
          "description": "name of the Kafka topic from which the consumer will read messages",
          "type": "string"
        }
      },
      "required": [
        "connectionName",
        "topic"
      ]
    },
    "KafkaProducerConfig": {
      "type": "object",
      "properties": {
        "config": {
          "description": "librdkafka Kafka consumer configuration properties. Do not include here Kafka configurations\nabout the Kafka instance and/or connection, as it will be overrided by the selected connection",
          "type": "object",
          "additionalProperties": {
            "$ref": "#/definitions/Secret"
          },
          "default": {}
        },
        "connectionName": {
          "description": "Connection name to use from the connections map (must be type kafka)\n\nThis property is required from version 0.6.0 onwards.",
          "type": "string"
        },
        "topic": {
          "description": "name of the Kafka topic to which the producer will send messages",
          "type": "string"
        }
      },
      "required": [
        "connectionName",
        "topic"
      ]
    },
    "MongodbCacheConfig": {
      "type": "object",
      "properties": {
        "appName": {
          "type": [
            "string",
            "null"
          ]
        },
        "collection": {
          "type": "string"
        },
        "connectionName": {
          "description": "Connection name to use from the connections map (must be type mongo/mongodb)\n\nThis property is required from version 0.6.0 onwards.",
          "type": "string"
        },
        "database": {
          "type": [
            "string",
            "null"
          ]
        }
      },
      "required": [
        "collection",
        "connectionName"
      ]
    },
    "MongodbConnectionConfig": {
      "type": "object",
      "properties": {
        "appName": {
          "type": [
            "string",
            "null"
          ]
        },
        "database": {
          "type": [
            "string",
            "null"
          ]
        },
        "url": {
          "$ref": "#/definitions/Secret"
        }
      },
      "required": [
        "url"
      ]
    },
    "MultiValue": {
      "type": "object",
      "properties": {
        "key": {
          "type": "string"
        },
        "value": {
          "$ref": "#/definitions/Secret"
        }
      },
      "required": [
        "key",
        "value"
      ]
    },
    "MultiValue2": {
      "type": "object",
      "properties": {
        "key": {
          "type": "string"
        },
        "value": {
          "type": "string"
        }
      },
      "required": [
        "key",
        "value"
      ]
    },
    "ProcessorConfig": {
      "oneOf": [
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "const": "javascript"
            }
          },
          "allOf": [
            {
              "$ref": "#/definitions/SandboxConfig"
            }
          ],
          "required": [
            "type"
          ]
        }
      ]
    },
    "ProcessorModeConfig": {
      "anyOf": [
        {
          "allOf": [
            {
              "type": "object",
              "properties": {
                "dlq": {
                  "$ref": "#/definitions/ProducerConfig"
                },
                "onError": {
                  "enum": [
                    "dlq"
                  ]
                }
              },
              "required": [
                "onError",
                "dlq"
              ]
            },
            {
              "$ref": "#/definitions/ProcessorConfig"
            }
          ]
        },
        {
          "allOf": [
            {
              "type": "object",
              "properties": {
                "onError": {
                  "enum": [
                    "fastFast",
                    "FailFast"
                  ]
                }
              }
            },
            {
              "$ref": "#/definitions/ProcessorConfig"
            }
          ]
        }
      ]
    },
    "ProducerConfig": {
      "oneOf": [
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "const": "kafka"
            }
          },
          "allOf": [
            {
              "$ref": "#/definitions/KafkaProducerConfig"
            }
          ],
          "required": [
            "type"
          ]
        }
      ]
    },
    "RestEndpointConfig": {
      "type": "object",
      "properties": {
        "headers": {
          "description": "Additional headers to include in the request.",
          "type": "array",
          "items": {
            "$ref": "#/definitions/MultiValue"
          }
        },
        "method": {
          "description": "A valid HTTP method",
          "type": "string",
          "enum": [
            "GET",
            "HEAD",
            "POST",
            "PUT",
            "DELETE",
            "CONNECT",
            "OPTIONS",
            "TRACE",
            "PATCH",
            "get",
            "head",
            "post",
            "put",
            "delete",
            "connect",
            "options",
            "trace",
            "patch",
            "Get",
            "Head",
            "Post",
            "Put",
            "Delete",
            "Connect",
            "Options",
            "Trace",
            "Patch"
          ]
        },
        "path": {
          "description": "The base URL of the FarmData service.",
          "allOf": [
            {
              "$ref": "#/definitions/Segments"
            }
          ]
        },
        "query": {
          "description": "Additional query parameters to include in the request.",
          "type": "array",
          "items": {
            "$ref": "#/definitions/MultiValue2"
          }
        }
      },
      "required": [
        "method",
        "path"
      ]
    },
    "SandboxConfig": {
      "type": "object",
      "properties": {
        "consoleBuffer": {
          "description": "Size in bytes available to the console object in the sandbox",
          "type": "integer",
          "format": "uint",
          "default": 1024,
          "minimum": 0
        },
        "interruptMs": {
          "description": "Max time in milliseconds a single function can be running within the sandbox",
          "type": "integer",
          "format": "uint64",
          "default": 5000,
          "minimum": 0
        },
        "maxHeapSize": {
          "description": "Max heap size in bytes. When not set quickjs's default will be used",
          "type": [
            "integer",
            "null"
          ],
          "format": "uint",
          "default": null,
          "minimum": 0
        },
        "maxStackSize": {
          "description": "Max stack size in bytes. When not set quickjs's default will be used",
          "type": [
            "integer",
            "null"
          ],
          "format": "uint",
          "default": null,
          "minimum": 0
        },
        "payloadSerdeStrategy": {
          "description": "Option to configure the deserialization\nfor incoming payload, a.k.a. the method to call\non payload before to inject it in the sandbox message argument",
          "allOf": [
            {
              "$ref": "#/definitions/SerdeSettings"
            }
          ],
          "default": {
            "deserialize": "json"
          }
        }
      }
    },
    "Secret": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "object",
          "properties": {
            "encoding": {
              "description": "Define which type of encoding the library supports when it needs to read the actual secret value.",
              "type": "string",
              "enum": [
                "base64"
              ]
            },
            "key": {
              "type": "string"
            },
            "type": {
              "const": "env"
            }
          },
          "required": [
            "type",
            "key"
          ]
        },
        {
          "type": "object",
          "properties": {
            "encoding": {
              "description": "Define which type of encoding the library supports when it needs to read the actual secret value.",
              "type": "string",
              "enum": [
                "base64"
              ]
            },
            "key": {
              "type": "string"
            },
            "path": {
              "type": "string"
            },
            "type": {
              "const": "file"
            }
          },
          "required": [
            "type",
            "path"
          ]
        }
      ],
      "examples": [
        "my-secret",
        {
          "key": "CUSTOM_ENV_VAR",
          "type": "env"
        },
        {
          "encoding": "base64",
          "key": "CUSTOM_ENV_VAR",
          "type": "env"
        },
        {
          "path": "/path/to/file",
          "type": "file"
        }
      ]
    },
    "Segments": {
      "type": "string"
    },
    "SerdeMode": {
      "description": "Describe which serialization or deserialization strategy\nshould be applied to the key of a Kafka message",
      "oneOf": [
        {
          "description": "serialize/deserialize the content as a JSON Object",
          "type": "string",
          "const": "json"
        },
        {
          "description": "serialize/deserialize the content as a JSON Object\nwith compatibility for schema+payload when\nKafka uses a schema registry. The payload is in a\nsubkey payload",
          "type": "string",
          "const": "jsonWithSchema"
        },
        {
          "description": "serialize/deserialize the key as a string: useful\nwhen payload bytes have to be processed raw inside the\nsandbox",
          "type": "string",
          "const": "string"
        }
      ]
    },
    "SerdeSettings": {
      "type": "object",
      "properties": {
        "deserialize": {
          "allOf": [
            {
              "$ref": "#/definitions/SerdeMode"
            }
          ],
          "default": "json"
        }
      }
    }
  }
}