<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="https://cev.gouv.mc/cev/schemas/kmc/me/manifest.xsd"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
           targetNamespace="https://cev.gouv.mc/cev/schemas/kmc/me/manifest.xsd"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">

    <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
    <xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd"/>

    <xs:element name="Manifest">
        <xs:annotation>
            <xs:documentation>Root element for a use case descriptor</xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="Id" />
                <xs:element ref="Version" />
                <xs:element ref="Name" />
                <xs:element ref="Description" />
                <xs:element ref="Schema" />
                <xs:element ref="Extensions" minOccurs="0"/>
                <xs:element ref="ds:Signature" minOccurs="0"/>
            </xs:sequence>
            <xs:attribute name="version" type="xs:int" use="required" fixed="1">
                <xs:annotation>
                    <xs:documentation>Manifest format version</xs:documentation>
                </xs:annotation>
            </xs:attribute>
        </xs:complexType>
    </xs:element>

    <xs:element name="Id">
        <xs:annotation>
            <xs:documentation>Use case unique identifier</xs:documentation>
        </xs:annotation>
        <xs:simpleType>
            <xs:restriction base="xs:string">
                <xs:pattern value="[0-9a-fA-F]{6}" />
            </xs:restriction>
        </xs:simpleType>
    </xs:element>

    <xs:element name="Version">
        <xs:annotation>
            <xs:documentation>Use case version to be incremented when a breaking change is introduced</xs:documentation>
        </xs:annotation>
        <xs:simpleType>
            <xs:restriction base="xs:string">
                <xs:pattern value="[0-9a-fA-F]{2}" />
            </xs:restriction>
        </xs:simpleType>
    </xs:element>

    <xs:element name="Name">
        <xs:annotation>
            <xs:documentation>Use case name</xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Value" type="ValueType" minOccurs="1" maxOccurs="unbounded" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="ValueType">
        <xs:annotation>
            <xs:documentation>Element used to define a translatable value</xs:documentation>
        </xs:annotation>
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute ref="xml:lang"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:element name="Description">
        <xs:annotation>
            <xs:documentation>Use Case description</xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Value" type="ValueType" minOccurs="1" maxOccurs="unbounded" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="Schema">
        <xs:annotation>
            <xs:documentation>Use case data schema to decode the VDS payload</xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:sequence>

                <xs:element name="Payload">
                    <xs:annotation>
                        <xs:documentation>Payload definition</xs:documentation>
                    </xs:annotation>
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="Fields" type="FieldsType">
                                <xs:annotation>
                                    <xs:documentation>List of fields defined in the payload</xs:documentation>
                                </xs:annotation>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>

                <xs:element name="AuxData" minOccurs="0">
                    <xs:annotation>
                        <xs:documentation>Auxiliary data definition</xs:documentation>
                    </xs:annotation>
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="Fields" type="FieldsType">
                                <xs:annotation>
                                    <xs:documentation>
                                        List of fields defined in the Auxiliary Data. Optional.
                                        If not specified, this means there are no auxiliary data.
                                    </xs:documentation>
                                </xs:annotation>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>

                <xs:element name="Types" minOccurs="0">
                    <xs:annotation>
                        <xs:documentation>List of custom object types defined by this schema</xs:documentation>
                    </xs:annotation>
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="Type" minOccurs="1" maxOccurs="unbounded">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="Fields" type="FieldsType" minOccurs="0"/>
                                    </xs:sequence>
                                    <xs:attribute name="name" type="xs:string" use="required">
                                        <xs:annotation>
                                            <xs:documentation>Type name. Must match any object in schema with same type.</xs:documentation>
                                        </xs:annotation>
                                    </xs:attribute>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>

            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="FieldsType">
        <xs:choice minOccurs="0" maxOccurs="unbounded">

            <xs:element name="String" type="StringType" minOccurs="0" maxOccurs="unbounded" />
            <xs:element name="Boolean" type="BooleanType" minOccurs="0" maxOccurs="unbounded" />
            <xs:element name="Integer" type="IntegerType" minOccurs="0" maxOccurs="unbounded" />
            <xs:element name="Float" type="FloatType" minOccurs="0" maxOccurs="unbounded" />
            <xs:element name="Date" type="DateType" minOccurs="0" maxOccurs="unbounded" />
            <xs:element name="Timestamp" type="TimestampType" minOccurs="0" maxOccurs="unbounded" />
            <xs:element name="Object" type="ObjectType" minOccurs="0" maxOccurs="unbounded" />

            <xs:element name="Binary" type="BinaryType" minOccurs="0" maxOccurs="unbounded" />
            <xs:element name="StringArray" type="StringArrayType" minOccurs="0" maxOccurs="unbounded" />
            <xs:element name="BooleanArray" type="BooleanArrayType" minOccurs="0" maxOccurs="unbounded" />
            <xs:element name="IntegerArray" type="IntegerArrayType" minOccurs="0" maxOccurs="unbounded" />
            <xs:element name="FloatArray" type="FloatArrayType" minOccurs="0" maxOccurs="unbounded" />
            <xs:element name="DateArray" type="DateArrayType" minOccurs="0" maxOccurs="unbounded" />
            <xs:element name="TimestampArray" type="TimestampArrayType" minOccurs="0" maxOccurs="unbounded" />
            <xs:element name="ObjectArray" type="ObjectArrayType" minOccurs="0" maxOccurs="unbounded" />
            <xs:element name="BinaryArray" type="BinaryArrayType" minOccurs="0" maxOccurs="unbounded" />

            <xs:element name="Image" type="ImageType" minOccurs="0" maxOccurs="1" />

        </xs:choice>
    </xs:complexType>

    <xs:complexType name="StringType">
        <xs:annotation>
            <xs:documentation>Field representing a sequence of characters. Constraints can be applied using StringConStraints element.</xs:documentation>
        </xs:annotation>
        <xs:complexContent>
            <xs:extension base="TypeDef">
                <xs:sequence>
                    <xs:element name="StringConstraints" type="StringConstraintsType" minOccurs="0" />
                    <xs:element name="Extension" minOccurs="0" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="TypeDef" abstract="true">
        <xs:annotation>
            <xs:documentation>Base entity for a schema field</xs:documentation>
        </xs:annotation>
        <xs:attribute name="name" type="xs:string" use="required" />
    </xs:complexType>

    <xs:complexType name="StringConstraintsType">
        <xs:complexContent>
            <xs:extension base="BaseConstraintsType">
                <xs:sequence>
                    <xs:choice minOccurs="0" maxOccurs="4">
                        <xs:element name="MinLength" type="xs:unsignedInt" minOccurs="0" />
                        <xs:element name="MaxLength" type="xs:unsignedInt" minOccurs="0" />
                        <xs:element name="Pattern" type="xs:string" minOccurs="0" />
                        <xs:element name="Encoding" minOccurs="0">
                            <xs:simpleType>
                                <xs:restriction base="xs:string">
                                    <xs:enumeration value="BASE32" />
                                    <xs:enumeration value="BASE64" />
                                    <xs:enumeration value="C40" />
                                </xs:restriction>
                            </xs:simpleType>
                        </xs:element>
                    </xs:choice>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="BaseConstraintsType" abstract="true">
        <xs:sequence>
            <xs:element name="Nillable" type="xs:string" minOccurs="0" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="StringArrayType">
        <xs:complexContent>
            <xs:extension base="ArrayType">
                <xs:sequence>
                    <xs:element name="StringConstraints" type="StringConstraintsType" minOccurs="0" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="ArrayType">
        <xs:complexContent>
            <xs:extension base="TypeDef">
                <xs:sequence>
                    <xs:element name="ArrayConstraints" type="ArrayConstraintsType" minOccurs="0" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="ArrayConstraintsType">
        <xs:complexContent>
            <xs:extension base="BaseConstraintsType">
                <xs:sequence>
                    <xs:choice minOccurs="0" maxOccurs="2">
                        <xs:element name="MinSize" type="xs:unsignedInt" minOccurs="0" />
                        <xs:element name="MaxSize" type="xs:unsignedInt" minOccurs="0" />
                    </xs:choice>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="BooleanType">
        <xs:complexContent>
            <xs:extension base="TypeDef">
                <xs:sequence>
                    <xs:element name="BooleanConstraints" type="BooleanConstraintsType" minOccurs="0" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="BooleanConstraintsType">
        <xs:complexContent>
            <xs:extension base="BaseConstraintsType" />
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="BooleanArrayType">
        <xs:complexContent>
            <xs:extension base="ArrayType">
                <xs:sequence>
                    <xs:element name="BooleanConstraints" type="BooleanConstraintsType" minOccurs="0" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="IntegerType">
        <xs:complexContent>
            <xs:extension base="TypeDef">
                <xs:sequence>
                    <xs:element name="IntegerConstraints" type="IntegerConstraintsType" minOccurs="0" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="IntegerConstraintsType">
        <xs:complexContent>
            <xs:extension base="BaseConstraintsType">
                <xs:sequence>
                    <xs:choice minOccurs="0" maxOccurs="3">
                        <xs:element name="Min" type="xs:long" minOccurs="0" />
                        <xs:element name="Max" type="xs:long" minOccurs="0" />
                        <xs:element name="Pattern" type="xs:string" minOccurs="0" />
                    </xs:choice>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="IntegerArrayType">
        <xs:complexContent>
            <xs:extension base="ArrayType">
                <xs:sequence>
                    <xs:element name="IntegerConstraints" type="IntegerConstraintsType" minOccurs="0" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="FloatType">
        <xs:complexContent>
            <xs:extension base="TypeDef">
                <xs:sequence>
                    <xs:element name="FloatConstraints" type="FloatConstraintsType" minOccurs="0" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="FloatConstraintsType">
        <xs:complexContent>
            <xs:extension base="BaseConstraintsType">
                <xs:sequence>
                    <xs:choice minOccurs="0" maxOccurs="2">
                        <xs:element name="Min" type="xs:decimal" minOccurs="0" />
                        <xs:element name="Max" type="xs:decimal" minOccurs="0" />
                    </xs:choice>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="FloatArrayType">
        <xs:complexContent>
            <xs:extension base="ArrayType">
                <xs:sequence>
                    <xs:element name="FloatConstraints" type="FloatConstraintsType" minOccurs="0" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="DateType">
        <xs:complexContent>
            <xs:extension base="TypeDef">
                <xs:sequence>
                    <xs:element name="DateConstraints" type="DateConstraintsType" minOccurs="0" />
                    <xs:element name="Extension" minOccurs="0" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="DateConstraintsType">
        <xs:complexContent>
            <xs:extension base="BaseConstraintsType">
                <xs:sequence>
                    <xs:choice minOccurs="0" maxOccurs="3">
                        <xs:element name="NotBefore" type="xs:date" minOccurs="0" />
                        <xs:element name="NotAfter" type="xs:date" minOccurs="0" />
                        <xs:element name="From" type="xs:date" minOccurs="0" />
                    </xs:choice>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="DateArrayType">
        <xs:complexContent>
            <xs:extension base="ArrayType">
                <xs:sequence>
                    <xs:element name="DateConstraints" type="DateConstraintsType" minOccurs="0" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="TimestampType">
        <xs:complexContent>
            <xs:extension base="TypeDef">
                <xs:sequence>
                    <xs:element name="TimestampConstraints" type="TimestampConstraintsType" minOccurs="0" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="TimestampConstraintsType">
        <xs:complexContent>
            <xs:extension base="BaseConstraintsType">
                <xs:sequence>
                    <xs:choice minOccurs="0" maxOccurs="2">
                        <xs:element name="NotBefore" type="xs:dateTime" minOccurs="0" />
                        <xs:element name="NotAfter" type="xs:dateTime" minOccurs="0" />
                    </xs:choice>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="TimestampArrayType">
        <xs:complexContent>
            <xs:extension base="ArrayType">
                <xs:sequence>
                    <xs:element name="TimestampConstraints" type="TimestampConstraintsType" minOccurs="0" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="ObjectType">
        <xs:complexContent>
            <xs:extension base="TypeDef">
                <xs:sequence>
                    <xs:element name="ObjectConstraints" type="ObjectConstraintsType" minOccurs="0"/>
                </xs:sequence>
                <xs:attribute name="type" type="xs:string" use="required">
                    <xs:annotation>
                        <xs:documentation>Type of object. Must be a reference to an object defined in Types.</xs:documentation>
                    </xs:annotation>
                </xs:attribute>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="ObjectConstraintsType">
        <xs:complexContent>
            <xs:extension base="BaseConstraintsType" />
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="ObjectArrayType">
        <xs:complexContent>
            <xs:extension base="ArrayType">
                <xs:sequence>
                    <xs:element name="ObjectConstraints" type="ObjectConstraintsType" minOccurs="0" />
                </xs:sequence>
                <xs:attribute name="type" type="xs:string" use="required" />
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="BinaryType">
        <xs:complexContent>
            <xs:extension base="TypeDef">
                <xs:sequence>
                    <xs:element name="BinaryConstraints" type="BinaryConstraintsType" minOccurs="0" />
                    <xs:element name="Extension" minOccurs="0" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="BinaryConstraintsType">
        <xs:complexContent>
            <xs:extension base="BaseConstraintsType">
                <xs:sequence>
                    <xs:choice minOccurs="0" maxOccurs="3">
                        <xs:element name="MinLength" type="xs:unsignedInt" minOccurs="0" />
                        <xs:element name="MaxLength" type="xs:unsignedInt" minOccurs="0" />
                        <xs:element name="Pattern" type="xs:string" minOccurs="0" />
                    </xs:choice>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="BinaryArrayType">
        <xs:complexContent>
            <xs:extension base="ArrayType">
                <xs:sequence>
                    <xs:element name="BinaryConstraints" type="BinaryConstraintsType" minOccurs="0" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="ImageType">
        <xs:complexContent>
            <xs:extension base="BinaryType">
                <xs:sequence>
                    <xs:element name="BinaryConstraints" type="BinaryConstraintsType" minOccurs="0" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:element name="Extensions">
        <xs:annotation>
            <xs:documentation>Extension point where new features can be added</xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Extension" type="ExtensionType" minOccurs="0" maxOccurs="unbounded" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="ExtensionType" abstract="true" />

    <xs:complexType name="FieldExtensionType" abstract="true">
        <xs:annotation>
            <xs:documentation>Base type for a field extension.</xs:documentation>
        </xs:annotation>
    </xs:complexType>

    <xs:complexType name="PoliciesExtensionType">
        <xs:complexContent>
            <xs:extension base="ExtensionType">
                <xs:sequence>
                    <xs:element name="AuthorizedUsage" type="AuthorizedUsageType" minOccurs="0" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="AuthorizedUsageType">
        <xs:sequence>
            <xs:element name="oid" minOccurs="1" maxOccurs="1">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:pattern value="([0-2](\.[0-9]+)+)" />
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
            <xs:element name="uuid" minOccurs="1" maxOccurs="1">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:pattern value="[a-f0-9A-Z]{32}" />
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

</xs:schema>
