<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ Copyright The WildFly Authors
  ~ SPDX-License-Identifier: Apache-2.0
  -->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="urn:jboss:domain:picketlink-identity-management:1.0"
            xmlns="urn:jboss:domain:picketlink-identity-management:1.0"
            elementFormDefault="qualified"
            attributeFormDefault="unqualified"
            version="1.0">

    <!-- The picketlink identity management subsystem root element -->
    <xsd:element name="subsystem" type="subsystemType"/>

    <xsd:complexType name="subsystemType">
      <xsd:sequence>
         <xsd:element name="partition-manager" type="partitionManagerType" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="partitionManagerType">
        <xsd:annotation>
            <xsd:documentation>Defines the Partition Manager type.</xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
          <xsd:element name="identity-configuration" type="identityConfigurationType" minOccurs="1" maxOccurs="unbounded" nillable="false"/>
        </xsd:sequence>
        <xsd:attribute name="name" type="xsd:string" use="required">
          <xsd:annotation>
            <xsd:documentation>Name for this instance.</xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="jndi-name" type="xsd:string" use="required">
          <xsd:annotation>
            <xsd:documentation>JNDI name to bind this instance.</xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>
    </xsd:complexType>

    <xsd:complexType name="identityConfigurationType">
        <xsd:annotation>
            <xsd:documentation>Defines the configuration for a Partition Manager type.</xsd:documentation>
        </xsd:annotation>
        <xsd:sequence minOccurs="1" maxOccurs="unbounded">
            <xsd:element name="jpa-store" type="jpaIdentityStoreType" minOccurs="0" maxOccurs="1" nillable="true"/>
            <xsd:element name="file-store" type="fileIdentityStoreType" minOccurs="0" maxOccurs="1" nillable="true"/>
            <xsd:element name="ldap-store" type="ldapIdentityStoreType" minOccurs="0" maxOccurs="1" nillable="true"/>
        </xsd:sequence>
        <xsd:attribute name="name" type="xsd:string" use="required">
            <xsd:annotation>
                <xsd:documentation>Name for this configuration.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
    </xsd:complexType>

    <xsd:complexType name="identityStoreType" abstract="true">
        <xsd:annotation>
            <xsd:documentation>Base schema for identity store elements.</xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
            <xsd:element name="supported-types" type="supportedTypesType" minOccurs="1" maxOccurs="1" nillable="false"/>
            <xsd:element name="credential-handlers" type="credentialHandlersType" minOccurs="0" maxOccurs="1" nillable="true"/>
        </xsd:sequence>
        <xsd:attribute name="support-credential" type="xsd:boolean" use="optional" default="true">
            <xsd:annotation>
                <xsd:documentation>Indicates if the store should support credentials management.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="support-attribute" type="xsd:boolean" use="optional" default="true">
            <xsd:annotation>
                <xsd:documentation>Indicates if the store should support attributes management.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
    </xsd:complexType>

    <xsd:complexType name="supportedTypesType">
        <xsd:annotation>
            <xsd:documentation>The supported-types element schema.</xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
            <xsd:element name="supported-type" type="supportedType" minOccurs="0" maxOccurs="unbounded" nillable="false"/>
        </xsd:sequence>
        <xsd:attribute name="supports-all" type="xsd:boolean" use="optional" default="true">
            <xsd:annotation>
                <xsd:documentation>Defines if all types and configurations are supported.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
    </xsd:complexType>

    <xsd:complexType name="supportedType">
        <xsd:annotation>
            <xsd:documentation>The supported-type element schema.</xsd:documentation>
        </xsd:annotation>
        <xsd:attribute name="class-name" type="xsd:string" use="optional">
            <xsd:annotation>
                <xsd:documentation>Defines a type that should be supported by a identity store.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="code" type="xsd:string" use="optional">
            <xsd:annotation>
                <xsd:documentation>Defines an alias which maps to a built-in type.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="module" type="xsd:string" use="optional">
            <xsd:annotation>
                <xsd:documentation>Defines the module to be used when loading class-name.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
    </xsd:complexType>

    <xsd:complexType name="credentialHandlersType">
        <xsd:annotation>
            <xsd:documentation>The credential-handlers element schema.</xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
            <xsd:element name="credential-handler" type="credentialHandlerType" minOccurs="0" maxOccurs="unbounded" nillable="false"/>
        </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="credentialHandlerType">
        <xsd:annotation>
            <xsd:documentation>The credential-handler element schema.</xsd:documentation>
        </xsd:annotation>
        <xsd:attribute name="class-name" type="xsd:string" use="optional">
            <xsd:annotation>
                <xsd:documentation>Defines a credential handler type that should be supported by a identity store.
                </xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="code" type="xsd:string" use="optional">
            <xsd:annotation>
                <xsd:documentation>Defines an alias which maps to a built-in type.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="module" type="xsd:string" use="optional">
            <xsd:annotation>
                <xsd:documentation>Defines the module to be used when loading class-name.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
    </xsd:complexType>

    <xsd:complexType name="jpaIdentityStoreType">
        <xsd:annotation>
            <xsd:documentation>Defines the schema for the JPA identity store configuration.</xsd:documentation>
        </xsd:annotation>
        <xsd:complexContent>
            <xsd:extension base="identityStoreType">
                <xsd:attribute name="entity-manager-factory" type="xsd:string" use="optional">
                    <xsd:annotation>
                        <xsd:documentation>The JNDI url of the EntityManagerFactory that should be used, instead of the default
                        factory.
                        </xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="data-source" type="xsd:string" use="optional">
                    <xsd:annotation>
                        <xsd:documentation>The JNDI url of data source that should be used to create the default
                        EntityManagerFactory.
                        </xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="entity-module" type="xsd:string" use="optional">
                    <xsd:annotation>
                        <xsd:documentation>The name of the module where the JPA entities are located. Those entities will be used to
                        initialize the JPA store.
                        </xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="entity-module-unit-name" type="xsd:string" use="optional" default="identity">
                    <xsd:annotation>
                        <xsd:documentation>The name of the persistence unit name, if the entity-module attribute is present.</xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="fileIdentityStoreType">
        <xsd:annotation>
            <xsd:documentation>Defines the schema for the File identity store configuration.</xsd:documentation>
        </xsd:annotation>
        <xsd:complexContent>
            <xsd:extension base="identityStoreType">
                <xsd:attribute name="working-dir" type="xsd:string" use="optional" default="picketlink/idm">
                    <xsd:annotation>
                        <xsd:documentation>The working directory where data is located. If relative-to is specified, the working-dir is relative to its value.</xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="relative-to" type="xsd:string" use="optional" default="jboss.server.data.dir">
                    <xsd:annotation>
                        <xsd:documentation>
                        One of the system-provided named paths (such as jboss.home.dir,
                        user.home, user.dir) relative to which the absolute path
                        will be calculated for the path specified in the file attribute.
                        </xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="always-create-files" type="xsd:boolean" use="optional" default="true">
                    <xsd:annotation>
                        <xsd:documentation>Defines if data should be always re-created between initializations.</xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="async-write" type="xsd:boolean" use="optional" default="false">
                    <xsd:annotation>
                        <xsd:documentation>Defines if asynchronous write is enabled.</xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="async-write-thread-pool" type="xsd:int" use="optional" default="5">
                    <xsd:annotation>
                        <xsd:documentation>The size of the thread pool if asynchronous writing is enabled.</xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="ldapIdentityStoreType">
        <xsd:annotation>
            <xsd:documentation>Defines the schema for the LDAP identity store configuration.</xsd:documentation>
        </xsd:annotation>
        <xsd:complexContent>
            <xsd:extension base="identityStoreType">
                <xsd:sequence>
                    <xsd:element name="mappings" type="mappingsType" minOccurs="1" maxOccurs="1" nillable="false"/>
                </xsd:sequence>
                <xsd:attribute name="url" type="xsd:string" use="required">
                    <xsd:annotation>
                        <xsd:documentation>The working directory where data is located.</xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="bind-dn" type="xsd:string" use="required">
                    <xsd:annotation>
                        <xsd:documentation>Defines if data should be always re-created between initializations.</xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="bind-credential" type="xsd:string" use="required">
                    <xsd:annotation>
                        <xsd:documentation>Defines if asynchronous write is enabled.</xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="base-dn-suffix" type="xsd:string" use="required">
                    <xsd:annotation>
                        <xsd:documentation>The size of the thread pool if asynchronous writing is enabled.</xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="mappingsType">
        <xsd:annotation>
            <xsd:documentation>The mappings element schema.</xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
            <xsd:element name="mapping" type="mappingType" minOccurs="1" maxOccurs="unbounded" nillable="false"/>
        </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="mappingType">
        <xsd:annotation>
            <xsd:documentation>The mapping element schema.</xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
            <xsd:element name="attribute" type="attributeType" minOccurs="1" maxOccurs="unbounded" nillable="false"/>
        </xsd:sequence>
        <xsd:attribute name="class-name" type="xsd:string" use="optional">
            <xsd:annotation>
                <xsd:documentation>Defines a type that should be supported by a identity store.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="code" type="xsd:string" use="optional">
            <xsd:annotation>
                <xsd:documentation>Defines an alias which maps to a built-in type.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="module" type="xsd:string" use="optional">
            <xsd:annotation>
                <xsd:documentation>Defines the module to be used when loading class-name.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="base-dn-suffix" type="xsd:string" use="optional">
            <xsd:annotation>
                <xsd:documentation>Defines a base DN suffix where entries are located.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="object-classes" type="xsd:string" use="optional">
            <xsd:annotation>
                <xsd:documentation>A comma separated list of object classes for entries.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="relates-to" type="xsd:string" use="optional">
            <xsd:annotation>
                <xsd:documentation>Tells that this mapping is related with another mapped type. Useful for relationship mappings.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="parent-membership-attribute-name" type="xsd:string" use="optional">
            <xsd:annotation>
                <xsd:documentation>The name of the LDAP attribute used to map parent-child relationships of the same type.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
    </xsd:complexType>

    <xsd:complexType name="attributeType">
        <xsd:annotation>
            <xsd:documentation>The attribute element schema.</xsd:documentation>
        </xsd:annotation>
        <xsd:attribute name="name" type="xsd:string" use="required">
            <xsd:annotation>
                <xsd:documentation>The name of the property of the type mapped to a LDAP attribute.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="ldap-name" type="xsd:string" use="required">
            <xsd:annotation>
                <xsd:documentation>The name of the LDAP attribute mapped to a type's property.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="is-identifier" type="xsd:boolean" use="optional" default="false">
            <xsd:annotation>
                <xsd:documentation>Indicates if this attribute is an identifier.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="read-only" type="xsd:boolean" use="optional" default="false">
            <xsd:annotation>
                <xsd:documentation>Marks an attribute as read only.</xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
    </xsd:complexType>
</xsd:schema>