<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="https://app.respresso.io/public/schema/flow.xsd" elementFormDefault="qualified" attributeFormDefault="unqualified">

	<xs:simpleType name="nodeId">
		<xs:restriction base="xs:string">
			<xs:pattern value="^[a-z][a-zA-Z0-9]*$"/>
		</xs:restriction>
	</xs:simpleType>

	<xs:simpleType name="structurePath">
		<xs:annotation>
			<xs:documentation>
				<br/>
				Define a path within an object.
				<br/>
				Supports the following formats:
				<br/>
				empty means root
				<br/>
				key1.key2
				<br/>
				key[n] -> gets the nth element (0 means first element)
				<br/>
				key1.key2[3].key3
				<br/>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string">
			<xs:pattern value="(^$|^([a-z][a-zA-Z0-9]*)(\[[0-9]+\])?(\.([a-z][a-zA-Z0-9]*)(\[[0-9]+\])?)*$)"/>
		</xs:restriction>
	</xs:simpleType>

	<xs:simpleType name="mergeType">
		<xs:annotation>
			<xs:documentation>
				<br/>
				Define how the object merging happens.
				<br/>
				Use 'override' to completely replace any object at the target path.
				<br/>
				Use 'megre' to deeply merge any object to the target path. (Non objects will override values on any path.)
				<br/>
				Use 'none' to define only dependency for execution ordering. (No data exchange happens on this connection.)
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string">
			<xs:enumeration value="override"/>
			<xs:enumeration value="merge"/>
			<xs:enumeration value="none"/>
		</xs:restriction>
	</xs:simpleType>


	<xs:simpleType name="predefinedNode">
		<xs:annotation>
			<xs:documentation>
				<br/>
				References a predefined node in the flow graph.
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string">
			<xs:enumeration value="@config"/>
			<xs:enumeration value="@input"/>
			<xs:enumeration value="@output"/>
		</xs:restriction>
	</xs:simpleType>

	<xs:simpleType name="customNode">
		<xs:annotation>
			<xs:documentation>
				<br/>
				References a custom node in the flow graph.
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string">
			<xs:pattern value="^((@input|@output)|[a-z][a-zA-Z0-9]*(/(@config|@input|@output))?)$"/>
		</xs:restriction>
	</xs:simpleType>

	<xs:simpleType name="nodeRef">
		<xs:annotation>
			<xs:documentation>
				<br/>
				References a node in the flow graph.
			</xs:documentation>
		</xs:annotation>
		<xs:union memberTypes="customNode predefinedNode"/>
	</xs:simpleType>


	<xs:simpleType name="timeUnit">
		<xs:annotation>
			<xs:documentation>
				<br/>
				Unit of time
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string">
			<xs:enumeration value="MINUTES"/>
		</xs:restriction>
	</xs:simpleType>

	<xs:element name="flow">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="nodes">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="processor" minOccurs="0" maxOccurs="unbounded">
								<xs:complexType mixed="true">
									<xs:attribute name="id" type="nodeId" use="required"/>
									<xs:attribute name="name" type="xs:string" use="required"/>
									<xs:attribute name="version" type="xs:positiveInteger" use="required"/>
									<xs:attribute name="timeout" type="xs:positiveInteger" use="optional" default="1"/>
									<xs:attribute name="timeoutUnit" type="timeUnit" use="optional" default="MINUTES"/>
									<xs:attribute name="configId" type="xs:string" use="optional"/>
								</xs:complexType>
							</xs:element>
							<xs:element name="sub-flow" minOccurs="0" maxOccurs="unbounded">
								<xs:complexType>
									<xs:attribute name="id" type="nodeId" use="required"/>
									<xs:attribute name="flowId" type="xs:string" use="required"/>
									<xs:attribute name="node" type="xs:string" use="optional" default="@output"/>
								</xs:complexType>
							</xs:element>
							<xs:element name="data" minOccurs="0" maxOccurs="unbounded">
								<xs:complexType mixed="true">
									<xs:attribute name="id" type="nodeId" use="required"/>
									<xs:attribute name="configId" type="xs:string" use="optional"/>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
					</xs:complexType>
				</xs:element>
				<xs:element name="connections">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="connection" maxOccurs="unbounded">
								<xs:complexType>
									<xs:attribute name="from" type="nodeRef" use="required"/>
									<xs:attribute name="to" type="nodeRef" use="required"/>
									<xs:attribute name="read" type="structurePath" use="optional" default=""/>
									<xs:attribute name="write" type="structurePath" use="optional" default=""/>
									<xs:attribute name="mergeType" type="mergeType" use="optional" default="override"/>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
					</xs:complexType>
				</xs:element>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
</xs:schema>