<?xml version="1.0"?>
<!--
  ~ Copyright Terracotta, Inc.
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~     http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<xs:schema version="1.0"
           xmlns:eh="http://www.ehcache.org/v3"
           xmlns:tc="http://www.ehcache.org/v3/clustered"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           targetNamespace="http://www.ehcache.org/v3/clustered">

  <xs:import namespace="http://www.ehcache.org/v3"/>

  <!--
    Service configuration elements
  -->
  <xs:element name="cluster" type="tc:cluster-spec" substitutionGroup="eh:service-creation-configuration">
    <xs:annotation>
      <xs:documentation xml:lang="en">
        Used within the /config/service element of an Ehcache configuration, this element
        describes cluster service properties.
      </xs:documentation>
    </xs:annotation>
  </xs:element>

  <xs:element name="server-side-config" type="tc:server-side-config-spec">
    <xs:annotation>
      <xs:documentation>
        Specifies the server-side configuration of the entity to be accessed and or created.
      </xs:documentation>
    </xs:annotation>
  </xs:element>

  <xs:complexType name="cluster-spec">
    <xs:sequence minOccurs="1" maxOccurs="1">
      <xs:element name="connection" type="tc:connection-spec" minOccurs="1" maxOccurs="1">
        <xs:annotation>
          <xs:documentation>
            Specifies the server endpoint to use for identifying cluster configuration.
          </xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="read-timeout" type="eh:time-type" minOccurs="0" maxOccurs="1">
        <xs:annotation>
          <xs:documentation>
            Specifies the amount of time a cache read operation will wait for a response from a cluster
            server before abandoning the cluster operation.
          </xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="write-timeout" type="eh:time-type" minOccurs="0" maxOccurs="1">
        <xs:annotation>
          <xs:documentation>
            Specifies the amount of time a cache write operation will wait for a response from a cluster
            server before abandoning the cluster operation.
          </xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="connection-timeout" type="eh:time-type" minOccurs="0" maxOccurs="1">
        <xs:annotation>
          <xs:documentation>
            Specifies the amount of time a cache will wait to connect to a cluster
            server before abandoning the cluster operation.
          </xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element ref="tc:server-side-config" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="connection-spec">
    <xs:attribute name="url" type="tc:connectionUrl" use="required">
      <xs:annotation>
        <xs:documentation xml:lang="en">
          Identifies a single cluster member by URL.
        </xs:documentation>
      </xs:annotation>
    </xs:attribute>
  </xs:complexType>

  <xs:simpleType name="connectionUrl">
    <xs:restriction base="xs:anyURI">
      <xs:pattern value="\w+://([^\]\[/?#@]+@)?[^:?#/]+(:[1-9][0-9]{0,4})?(,([^\]\[/?#@]+@)?[^:?#/]+(:[1-9][0-9]{0,4})?)*(/[^\?#]*)?(\?[^#]*)?(#.*)?"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:complexType name="server-side-config-spec">
    <xs:sequence>
      <xs:element name="default-resource" type="tc:default-resource-spec" minOccurs="0" maxOccurs="1">
        <xs:annotation>
          <xs:documentation>
            Specifies the default server-side storage resource to use for storing cache data.
          </xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="shared-pool" type="tc:shared-pool-spec" minOccurs="0" maxOccurs="unbounded">
        <xs:annotation>
          <xs:documentation>
            Defines a pool of server-side storage resource to be shared amongst multiple caches.
          </xs:documentation>
        </xs:annotation>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="auto-create" type="xs:boolean" use="optional" default="false">
      <xs:annotation>
        <xs:documentation> xml:lang="en">
          True if server side components should be automatically created if they are absent.
        </xs:documentation>
      </xs:annotation>
    </xs:attribute>
  </xs:complexType>


  <xs:complexType name="default-resource-spec">
    <xs:attributeGroup ref="tc:from-required"/>
  </xs:complexType>

  <xs:complexType name="shared-pool-spec">
    <xs:complexContent>
      <xs:extension base="eh:memory-type">
        <xs:attribute name="name" type="xs:string" use="required">
          <xs:annotation>
            <xs:documentation>
              Shared pool name.
            </xs:documentation>
          </xs:annotation>
        </xs:attribute>
        <xs:attributeGroup ref="tc:from-optional"/>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:element name="clustered-dedicated" type="tc:clustered-dedicated-resource-type" substitutionGroup="eh:resource">
    <xs:annotation>
      <xs:documentation>
        Clustered cache resource with a dedicated size.
      </xs:documentation>
    </xs:annotation>
  </xs:element>

  <xs:complexType name="clustered-dedicated-resource-type">
    <xs:complexContent>
      <xs:extension base="eh:memory-type">
        <xs:attributeGroup ref="tc:from-optional"/>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:element name="clustered-shared" type="tc:clustered-shared-resource-type" substitutionGroup="eh:resource">
    <xs:annotation>
      <xs:documentation>
        Clustered cache resource sharing a pool with other cache resources.
      </xs:documentation>
    </xs:annotation>
  </xs:element>

  <xs:complexType name="clustered-shared-resource-type">
    <xs:attribute name="sharing" type="xs:string" use="required">
      <xs:annotation>
        <xs:documentation>
          Name of the shared pool this resource uses.
        </xs:documentation>
      </xs:annotation>
    </xs:attribute>
  </xs:complexType>

  <xs:element name="clustered" substitutionGroup="eh:resource">
    <xs:annotation>
      <xs:documentation>
        Clustered cache resource which inherits the resource pool configured on the server.
      </xs:documentation>
    </xs:annotation>
    <xs:complexType/>
  </xs:element>

  <xs:attributeGroup name="from-optional">
    <xs:attribute name="from" type="xs:string" use="optional">
      <xs:annotation>
        <xs:documentation>
          Optional reference to a server-side storage resource.
        </xs:documentation>
      </xs:annotation>
    </xs:attribute>
  </xs:attributeGroup>

  <xs:attributeGroup name="from-required">
    <xs:attribute name="from" type="xs:string" use="required">
      <xs:annotation>
        <xs:documentation>
          Required reference to a server-side storage resource.
        </xs:documentation>
      </xs:annotation>
    </xs:attribute>
  </xs:attributeGroup>

  <xs:element name="clustered-store" type="tc:clustered-store-type" substitutionGroup="eh:service-configuration"/>

  <xs:complexType name="clustered-store-type">
    <xs:attribute name="consistency" type="tc:consistency-type" default="eventual"/>
  </xs:complexType>

  <xs:simpleType name="consistency-type">
    <xs:restriction base="xs:string">
      <xs:enumeration value="eventual"/>
      <xs:enumeration value="strong"/>
    </xs:restriction>
  </xs:simpleType>
</xs:schema>
