<?xml version="1.0" encoding="UTF-8"?>

<!--
  ~ Copyright The WildFly Authors
  ~ SPDX-License-Identifier: Apache-2.0
  -->
<xs:schema targetNamespace="urn:jboss:domain:distributable-web:2.0"
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            xmlns:tns="urn:jboss:domain:distributable-web:2.0"
            elementFormDefault="qualified"
            attributeFormDefault="unqualified"
            version="2.0">

    <xs:element name="subsystem" type="tns:subsystem"/>

    <xs:complexType name="subsystem">
        <xs:sequence>
            <xs:choice maxOccurs="unbounded">
                <xs:element name="infinispan-session-management" type="tns:infinispan-session-management">
                    <xs:annotation>
                        <xs:documentation>Defines an Infinispan cache-based session management provider</xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="hotrod-session-management" type="tns:hotrod-session-management">
                    <xs:annotation>
                        <xs:documentation>Defines a deployment specific HotRod remote cache-based session management provider</xs:documentation>
                    </xs:annotation>
                </xs:element>
            </xs:choice>
            <xs:choice maxOccurs="unbounded">
                <xs:element name="infinispan-single-sign-on-management" type="tns:infinispan-single-sign-on-management">
                    <xs:annotation>
                        <xs:documentation>Defines an Infinispan cache-based single sign-on management provider</xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="hotrod-single-sign-on-management" type="tns:hotrod-single-sign-on-management">
                    <xs:annotation>
                        <xs:documentation>Defines an HotRod remote cache-based single sign-on management provider</xs:documentation>
                    </xs:annotation>
                </xs:element>
            </xs:choice>
            <xs:choice>
                <xs:element name="local-routing" type="tns:empty">
                    <xs:annotation>
                        <xs:documentation>Configures support for local routing</xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="infinispan-routing" type="tns:infinispan-routing">
                    <xs:annotation>
                        <xs:documentation>Configures support for cluster-aware routing</xs:documentation>
                    </xs:annotation>
                </xs:element>
            </xs:choice>
        </xs:sequence>
        <xs:attribute name="default-session-management" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>Identifies the default session management provider for distributable web applications</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="default-single-sign-on-management" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>Identifies the default single sign-on management provider</xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="abstract-session-management" abstract="true">
        <xs:attribute name="name" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>Uniquely identifies this session management provider.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="granularity" type="tns:granularity" use="required">
            <xs:annotation>
                <xs:documentation>Defines the granularity of cache entry mapping for the attributes of a session.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="abstract-single-sign-on-management" abstract="true">
        <xs:attribute name="name" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>Uniquely identifies this single sign-on management provider.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="infinispan-session-management">
        <xs:complexContent>
            <xs:extension base="tns:abstract-session-management">
                <xs:choice>
                    <xs:group ref="tns:affinity"/>
                    <xs:element name="primary-owner-affinity" type="tns:empty">
                        <xs:annotation>
                            <xs:documentation>
                                Web requests will have an affinity for the primary owner of a given session.
                                Behaves the same as local-affinity if the backing cache is not distributed nor replicated.
                            </xs:documentation>
                        </xs:annotation>
                    </xs:element>
                    <xs:element name="ranked-affinity" type="tns:ranked-affinity">
                        <xs:annotation>
                            <xs:documentation>
                                Web requests will have an affinity for the first available node in a list comprised of: primary owner, backup nodes, local node (if not a primary nor backup owner).
                                Behaves the same as local-affinity if the cache is not distributed, nor replicated.
                                Must be explicitly supported by the load balancer.
                            </xs:documentation>
                        </xs:annotation>
                    </xs:element>
                </xs:choice>
                <xs:attributeGroup ref="tns:infinispan"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="infinispan-single-sign-on-management">
        <xs:complexContent>
            <xs:extension base="tns:abstract-single-sign-on-management">
                <xs:attributeGroup ref="tns:infinispan"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="hotrod-session-management">
        <xs:complexContent>
            <xs:extension base="tns:abstract-session-management">
                <xs:choice>
                    <xs:element name="no-affinity" type="tns:empty">
                        <xs:annotation>
                            <xs:documentation>
                                Web requests not have an affinity for any particular server.
                                Intended for use cases where web session state is not maintained within the application server.
                            </xs:documentation>
                        </xs:annotation>
                    </xs:element>
                    <xs:element name="local-affinity" type="tns:empty">
                        <xs:annotation>
                            <xs:documentation>
                                Web requests have an affinity for the member that last handled a given session.
                                This option corresponds to traditional sticky session behavior.
                            </xs:documentation>
                        </xs:annotation>
                    </xs:element>
                </xs:choice>
                <xs:attributeGroup ref="tns:hotrod"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="hotrod-single-sign-on-management">
        <xs:complexContent>
            <xs:extension base="tns:abstract-single-sign-on-management">
                <xs:attributeGroup ref="tns:hotrod"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="infinispan-routing">
        <xs:attributeGroup ref="tns:infinispan"/>
    </xs:complexType>

    <xs:attributeGroup name="infinispan">
        <xs:attribute name="cache-container" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>References a cache-container defined by the Infinispan subsystem.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="cache" type="xs:string">
            <xs:annotation>
                <xs:documentation>
                    References a cache within the associated cache-container.
                    If unspecified, the default cache of the associated cache-container is assumed.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:attributeGroup>

    <xs:attributeGroup name="hotrod">
        <xs:attribute name="remote-cache-container" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>References a remote-cache-container defined by the Infinispan subsystem.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="cache-configuration" type="xs:string">
            <xs:annotation>
                <xs:documentation>References a named configuration on the remote server.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:attributeGroup>

    <xs:simpleType name="granularity">
        <xs:restriction base="xs:token">
            <xs:enumeration value="SESSION">
                <xs:annotation>
                    <xs:documentation>
                        Stores all session attributes within a single cache entry.
                        Generally more expensive than ATTRIBUTE granularity, but preserves any cross-attribute object references.
                    </xs:documentation>
                </xs:annotation>
            </xs:enumeration>
            <xs:enumeration value="ATTRIBUTE">
                <xs:annotation>
                    <xs:documentation>
                        Stores each session attribute within a separate cache entry.
                        Generally more efficient than SESSION granularity, but does not preserve any cross-attribute object references.
                    </xs:documentation>
                </xs:annotation>
            </xs:enumeration>
        </xs:restriction>
    </xs:simpleType>

    <xs:group name="affinity">
        <xs:choice>
            <xs:element name="no-affinity" type="tns:empty">
                <xs:annotation>
                    <xs:documentation>
                        Web requests not have an affinity for any particular server.
                        Intended for use cases where web session state is not maintained within the application server.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="local-affinity" type="tns:empty">
                <xs:annotation>
                    <xs:documentation>
                        Web requests have an affinity for the member that last handled a given session.
                        This option corresponds to traditional sticky session behavior.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:choice>
    </xs:group>

    <xs:complexType name="ranked-affinity">
        <xs:attribute name="delimiter" type="xs:string" default=".">
            <xs:annotation>
                <xs:documentation>The delimiter used to separate ranked routes within the session ID.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="max-routes" type="xs:string" default="3">
            <xs:annotation>
                <xs:documentation>The maximum number of routes to append to the session ID.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="empty">
        <xs:sequence/>
    </xs:complexType>
</xs:schema>