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

<!--
  ~ Copyright The WildFly Authors
  ~ SPDX-License-Identifier: Apache-2.0
  -->

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="urn:jboss:domain:logging:4.0"
           xmlns="urn:jboss:domain:logging:4.0"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified"
           version="4.0">

    <!-- The logging subsystem root element -->
    <xs:element name="subsystem" type="subsystem"/>

    <xs:complexType name="subsystem">
        <xs:annotation>
            <xs:documentation>
                <![CDATA[
                The configuration of the logging subsystem.
            ]]>
            </xs:documentation>
        </xs:annotation>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="logger" type="loggerType"/>
            <xs:element name="root-logger" type="rootLoggerType"/>
            <xs:element name="console-handler" type="consoleHandlerType"/>
            <xs:element name="file-handler" type="fileHandlerType"/>
            <xs:element name="periodic-rotating-file-handler" type="periodicFileHandlerType"/>
            <xs:element name="periodic-size-rotating-file-handler" type="periodicSizeFileHandlerType"/>
            <xs:element name="size-rotating-file-handler" type="sizeFileHandlerType"/>
            <xs:element name="async-handler" type="asyncHandlerType"/>
            <xs:element name="custom-handler" type="customHandlerType"/>
            <xs:element name="syslog-handler" type="syslogHandlerType"/>
            <xs:element name="formatter" type="formatterType"/>
            <xs:element name="add-logging-api-dependencies" type="booleanTrueValueType">
                <xs:annotation>
                    <xs:documentation>
                        <![CDATA[
                            Determines whether or not the default logging dependencies should be added to deployments during the deployment process.
                        ]]>
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="use-deployment-logging-config" type="booleanTrueValueType">
                <xs:annotation>
                    <xs:documentation>
                            Determines whether or not deployments should be scanned for configuration files. If set to
                            true and a configuration file is found the log manager will be configured based on the
                            configuration file.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="logging-profiles" type="logging-profilesType" minOccurs="0" maxOccurs="1"/>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="logging-profilesType">
        <xs:annotation>
            <xs:documentation>
                Contains a list of profiles available for use in deployments
            </xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:element name="logging-profile" type="logging-profileType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="logging-profileType">
        <xs:annotation>
            <xs:documentation>
                A logging profile that can be used in a deployment for a custom logging configuration.
            </xs:documentation>
        </xs:annotation>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="logger" type="loggerType"/>
            <xs:element name="root-logger" type="rootLoggerType"/>
            <xs:element name="console-handler" type="consoleHandlerType"/>
            <xs:element name="file-handler" type="fileHandlerType"/>
            <xs:element name="periodic-rotating-file-handler" type="periodicFileHandlerType"/>
            <xs:element name="periodic-size-rotating-file-handler" type="periodicSizeFileHandlerType"/>
            <xs:element name="size-rotating-file-handler" type="sizeFileHandlerType"/>
            <xs:element name="async-handler" type="asyncHandlerType"/>
            <xs:element name="custom-handler" type="customHandlerType"/>
            <xs:element name="syslog-handler" type="syslogHandlerType"/>
            <xs:element name="formatter" type="formatterType"/>
        </xs:choice>
        <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>

    <xs:complexType name="propertiesType">
        <xs:annotation>
            <xs:documentation>
                A collection of free-form properties.
            </xs:documentation>
        </xs:annotation>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="property">
                <xs:complexType>
                    <xs:attribute name="name" type="xs:string" use="required"/>
                    <xs:attribute name="value" type="xs:string" use="optional"/>
                </xs:complexType>
            </xs:element>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="refType">
        <xs:annotation>
            <xs:documentation>
                A named reference to another object.
            </xs:documentation>
        </xs:annotation>
        <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>

    <xs:complexType name="handlersType">
        <xs:annotation>
            <xs:documentation>
                A collection of handlers to apply to the enclosing object.
            </xs:documentation>
        </xs:annotation>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="handler" type="refType"/>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="rootLoggerType">
        <xs:annotation>
            <xs:documentation>
                Defines the root logger for this log context.
            </xs:documentation>
        </xs:annotation>
        <xs:all minOccurs="1" maxOccurs="1">
            <xs:element name="level" type="refType" minOccurs="0"/>
            <xs:element name="filter-spec" type="valueType" minOccurs="0"/>
            <xs:element name="handlers" type="handlersType" minOccurs="0"/>
        </xs:all>
    </xs:complexType>

    <xs:complexType name="loggerType">
        <xs:annotation>
            <xs:documentation>
                Defines a logger category.
            </xs:documentation>
        </xs:annotation>
        <xs:complexContent>
            <xs:extension base="rootLoggerType">
                <xs:attribute name="use-parent-handlers" type="xs:boolean" use="optional" default="true"/>
                <xs:attribute name="category" type="xs:string" use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="consoleHandlerType">
        <xs:annotation>
            <xs:documentation>
                Defines a handler which writes to the console.
            </xs:documentation>
        </xs:annotation>
        <xs:all>
            <xs:element name="level" type="refType" minOccurs="0"/>
            <xs:element name="encoding" type="valueType" minOccurs="0"/>
            <xs:element name="filter-spec" type="valueType" minOccurs="0"/>
            <xs:element name="formatter" type="handlerFormatterType" minOccurs="0"/>
            <xs:element name="target" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="name" use="required">
                        <xs:simpleType>
                            <xs:restriction base="xs:token">
                                <xs:enumeration value="System.out"/>
                                <xs:enumeration value="System.err"/>
                                <xs:enumeration value="console"/>
                            </xs:restriction>
                        </xs:simpleType>
                    </xs:attribute>
                </xs:complexType>
            </xs:element>
        </xs:all>
        <xs:attribute name="autoflush" type="xs:boolean" use="optional" default="true"/>
        <xs:attribute name="name" type="xs:string" use="required"/>
        <xs:attribute name="enabled" type="xs:boolean" use="optional" default="true"/>
    </xs:complexType>

    <xs:complexType name="fileHandlerType">
        <xs:annotation>
            <xs:documentation>
                Defines a handler which writes to a file.
            </xs:documentation>
        </xs:annotation>
        <xs:all>
            <xs:element name="level" type="refType" minOccurs="0"/>
            <xs:element name="encoding" type="valueType" minOccurs="0"/>
            <xs:element name="filter-spec" type="valueType" minOccurs="0"/>
            <xs:element name="formatter" type="handlerFormatterType" minOccurs="0"/>
            <xs:element name="file" type="pathType" minOccurs="1"/>
            <xs:element name="append" type="booleanValueType" minOccurs="0"/>
        </xs:all>
        <xs:attribute name="autoflush" type="xs:boolean" use="optional" default="true"/>
        <xs:attribute name="name" type="xs:string" use="required"/>
        <xs:attribute name="enabled" type="xs:boolean" use="optional" default="true"/>
    </xs:complexType>

    <xs:complexType name="periodicFileHandlerType">
        <xs:annotation>
            <xs:documentation>
                Defines a handler which writes to a file, rotating the log after a time period derived from the given
                suffix string, which should be in a format understood by java.text.SimpleDateFormat.
            </xs:documentation>
        </xs:annotation>
        <xs:all>
            <xs:element name="level" type="refType" minOccurs="0"/>
            <xs:element name="encoding" type="valueType" minOccurs="0"/>
            <xs:element name="filter-spec" type="valueType" minOccurs="0"/>
            <xs:element name="formatter" type="handlerFormatterType" minOccurs="0"/>
            <xs:element name="file" type="pathType"/>
            <xs:element name="suffix" type="valueType"/>
            <xs:element name="append" type="booleanValueType" minOccurs="0"/>
        </xs:all>
        <xs:attribute name="autoflush" type="xs:boolean" use="optional" default="true"/>
        <xs:attribute name="name" type="xs:string" use="required"/>
        <xs:attribute name="enabled" type="xs:boolean" use="optional" default="true"/>
    </xs:complexType>

    <xs:complexType name="periodicSizeFileHandlerType">
        <xs:annotation>
            <xs:documentation>
                Defines a handler which writes to a file, rotating the log after the size of the file grows beyond a
                certain point or the time period derived from the given suffix string and keeping a fixed number of
                backups. The suffix should be in a format understood by java.text.SimpleDateFormat.
            </xs:documentation>
        </xs:annotation>
        <xs:all>
            <xs:element name="level" type="refType" minOccurs="0"/>
            <xs:element name="encoding" type="valueType" minOccurs="0"/>
            <xs:element name="filter-spec" type="valueType" minOccurs="0"/>
            <xs:element name="formatter" type="handlerFormatterType" minOccurs="0"/>
            <xs:element name="file" type="pathType"/>
            <xs:element name="rotate-size" type="sizeType" minOccurs="0"/>
            <xs:element name="max-backup-index" type="positiveIntType" minOccurs="0"/>
            <xs:element name="suffix" type="valueType"/>
            <xs:element name="append" type="booleanValueType" minOccurs="0"/>
        </xs:all>
        <xs:attribute name="autoflush" type="xs:boolean" use="optional" default="true"/>
        <xs:attribute name="name" type="xs:string" use="required"/>
        <xs:attribute name="enabled" type="xs:boolean" use="optional" default="true"/>
        <xs:attribute name="rotate-on-boot" type="xs:boolean" use="optional" default="false"/>
    </xs:complexType>

    <xs:complexType name="sizeFileHandlerType">
        <xs:annotation>
            <xs:documentation>
                Defines a handler which writes to a file, rotating the log after the size of the file grows beyond a
                certain point and keeping a fixed number of backups.
            </xs:documentation>
        </xs:annotation>
        <xs:all>
            <xs:element name="level" type="refType" minOccurs="0"/>
            <xs:element name="encoding" type="valueType" minOccurs="0"/>
            <xs:element name="filter-spec" type="valueType" minOccurs="0"/>
            <xs:element name="formatter" type="handlerFormatterType" minOccurs="0"/>
            <xs:element name="file" type="pathType"/>
            <xs:element name="rotate-size" type="sizeType" minOccurs="0"/>
            <xs:element name="max-backup-index" type="positiveIntType" minOccurs="0"/>
            <xs:element name="suffix" type="valueType" minOccurs="0"/>
            <xs:element name="append" type="booleanValueType" minOccurs="0"/>
        </xs:all>
        <xs:attribute name="autoflush" type="xs:boolean" use="optional" default="true"/>
        <xs:attribute name="name" type="xs:string" use="required"/>
        <xs:attribute name="enabled" type="xs:boolean" use="optional" default="true"/>
        <xs:attribute name="rotate-on-boot" type="xs:boolean" use="optional" default="false"/>
    </xs:complexType>

    <xs:complexType name="asyncHandlerType">
        <xs:annotation>
            <xs:documentation>
                Defines a handler which writes to the sub-handlers in an asynchronous thread. Used for handlers which
                introduce a substantial amount of lag.
            </xs:documentation>
        </xs:annotation>
        <xs:all>
            <xs:element name="level" type="refType" minOccurs="0"/>
            <xs:element name="filter-spec" type="valueType" minOccurs="0"/>
            <xs:element name="queue-length" type="queueLengthType" minOccurs="1" maxOccurs="1"/>
            <xs:element name="overflow-action" type="overflowActionType" minOccurs="0"/>
            <xs:element name="subhandlers" type="handlersType"/>
        </xs:all>
        <xs:attribute name="name" type="xs:string" use="required"/>
        <xs:attribute name="enabled" type="xs:boolean" use="optional" default="true"/>
    </xs:complexType>

    <xs:complexType name="customHandlerType">
        <xs:annotation>
            <xs:documentation>
                Defines a custom handler.
            </xs:documentation>
        </xs:annotation>
        <xs:all>
            <xs:element name="level" type="refType" minOccurs="0"/>
            <xs:element name="encoding" type="valueType" minOccurs="0"/>
            <xs:element name="filter-spec" type="valueType" minOccurs="0"/>
            <xs:element name="formatter" type="handlerFormatterType" minOccurs="0"/>
            <xs:element name="properties" type="propertiesType" minOccurs="0"/>
        </xs:all>
        <xs:attribute name="name" type="xs:string" use="required"/>
        <xs:attribute name="module" type="xs:string" use="required"/>
        <xs:attribute name="class" type="xs:string" use="required"/>
        <xs:attribute name="enabled" type="xs:boolean" use="optional" default="true"/>
    </xs:complexType>

    <xs:complexType name="syslogHandlerType">
        <xs:annotation>
            <xs:documentation>
                Defines a syslog handler for UNIX/Linux based operating systems.
            </xs:documentation>
        </xs:annotation>
        <xs:all>
            <xs:element name="level" type="refType" minOccurs="0"/>
            <xs:element name="server-address" type="valueType" minOccurs="0" maxOccurs="1">
                <xs:annotation>
                    <xs:documentation>
                        The address of the syslog server. The default is localhost.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="hostname" type="valueType" minOccurs="0" maxOccurs="1">
                <xs:annotation>
                    <xs:documentation>
                        The name of the host the messages are being sent from. For example the name of the host the
                        application server is running on.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="port" type="positiveIntType" minOccurs="0" maxOccurs="1">
                <xs:annotation>
                    <xs:documentation>
                        The port the syslog server is listening on. The default is 514.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="app-name" type="valueType" minOccurs="0" maxOccurs="1">
                <xs:annotation>
                    <xs:documentation>
                        The app name used when formatting the message in RFC5424 format. By default the app name is
                        &quot;java&quot;
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="formatter" type="syslogFormatterType" minOccurs="0" maxOccurs="1"/>
            <xs:element name="facility" type="facilityType" minOccurs="0" maxOccurs="1"/>
        </xs:all>
        <xs:attribute name="name" type="xs:string" use="required"/>
        <xs:attribute name="enabled" type="xs:boolean" use="optional" default="true"/>
    </xs:complexType>

    <xs:complexType name="queueLengthType">
        <xs:attribute name="value" use="required">
            <xs:simpleType>
                <xs:restriction base="xs:positiveInteger">
                    <xs:minExclusive value="1"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="overflowActionType">
        <xs:attribute name="value" use="required">
            <xs:simpleType>
                <xs:restriction base="xs:token">
                    <xs:enumeration value="block"/>
                    <xs:enumeration value="discard"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="positiveIntType">
        <xs:attribute name="value" use="required" type="xs:positiveInteger"/>
    </xs:complexType>

    <xs:complexType name="booleanValueType">
        <xs:attribute name="value" use="required" type="xs:boolean"/>
    </xs:complexType>

    <xs:complexType name="booleanTrueValueType">
        <xs:attribute name="value" type="xs:boolean" default="true"/>
    </xs:complexType>

    <xs:complexType name="valueType">
        <xs:attribute name="value" use="required" type="xs:string"/>
    </xs:complexType>

    <xs:complexType name="pathType">
        <xs:attribute name="relative-to" use="optional" type="xs:string"/>
        <xs:attribute name="path" use="required" type="xs:string"/>
    </xs:complexType>

    <xs:complexType name="sizeType">
        <xs:attribute name="value">
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <!-- XSD doesn't allow ^ or $ so ^[0-9]+[bkmgtp]?$ is invalid -->
                    <xs:pattern value="[0-9]+[bkmgtp]"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="facilityType">
        <xs:annotation>
            <xs:documentation>
                Facility as defined by RFC-5424 (http://tools.ietf.org/html/rfc5424)and RFC-3164
                (http://tools.ietf.org/html/rfc3164).
            </xs:documentation>
        </xs:annotation>
        <xs:attribute name="value" use="required">
            <xs:simpleType>
                <xs:restriction base="xs:token">
                    <xs:enumeration value="kernel"/>
                    <xs:enumeration value="user-level"/>
                    <xs:enumeration value="mail-system"/>
                    <xs:enumeration value="system-daemons"/>
                    <xs:enumeration value="security"/>
                    <xs:enumeration value="syslogd"/>
                    <xs:enumeration value="line-printer"/>
                    <xs:enumeration value="network-news"/>
                    <xs:enumeration value="uucp"/>
                    <xs:enumeration value="clock-daemon"/>
                    <xs:enumeration value="security2"/>
                    <xs:enumeration value="ftp-daemon"/>
                    <xs:enumeration value="ntp"/>
                    <xs:enumeration value="log-audit"/>
                    <xs:enumeration value="log-alert"/>
                    <xs:enumeration value="clock-daemon2"/>
                    <xs:enumeration value="local-use-0"/>
                    <xs:enumeration value="local-use-1"/>
                    <xs:enumeration value="local-use-2"/>
                    <xs:enumeration value="local-use-3"/>
                    <xs:enumeration value="local-use-4"/>
                    <xs:enumeration value="local-use-5"/>
                    <xs:enumeration value="local-use-6"/>
                    <xs:enumeration value="local-use-7"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
    </xs:complexType>

    <!-- Formatters -->

    <xs:complexType name="formatterType">
        <xs:annotation>
            <xs:documentation>
                A formatter that can be assigned to a handler.
            </xs:documentation>
        </xs:annotation>
        <xs:choice minOccurs="1" maxOccurs="1">
            <xs:element name="pattern-formatter" type="patternFormatterType" maxOccurs="1"/>
            <xs:element name="custom-formatter" type="customFormatterType" maxOccurs="1"/>
        </xs:choice>
        <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>

    <xs:complexType name="handlerFormatterType">
        <xs:annotation>
            <xs:documentation>
                Defines a formatter.
            </xs:documentation>
        </xs:annotation>
        <xs:choice minOccurs="1" maxOccurs="1">
            <xs:element name="pattern-formatter" type="handlerPatternFormatterType" maxOccurs="1"/>
            <xs:element name="named-formatter" type="namedFormatterType" maxOccurs="1"/>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="handlerPatternFormatterType">
        <xs:annotation>
            <xs:documentation>
                Defines a pattern formatter. See the documentation for
                org.jboss.logmanager.formatters.FormatStringParser
                for more information about the format string.
            </xs:documentation>
        </xs:annotation>
        <xs:attribute name="pattern" type="xs:string" use="required"/>
    </xs:complexType>

    <xs:complexType name="patternFormatterType">
        <xs:annotation>
            <xs:documentation>
                Defines a pattern formatter. See the documentation for
                org.jboss.logmanager.formatters.FormatStringParser
                for more information about the format string.

                The color-map attribute allows for a comma delimited list of colors to be used for different levels. The
                format is level-name:color-name.

                Valid Levels; severe, fatal, error, warn, warning, info, debug, trace, config, fine, finer, finest

                Valid Colors; black, green, red, yellow, blue, magenta, cyan, white, brightblack, brightred,
                brightgreen,
                brightblue, brightyellow, brightmagenta, brightcyan, brightwhite
            </xs:documentation>
        </xs:annotation>
        <xs:attribute name="pattern" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>
                    The format pattern as defined in org.jboss.logmanager.formatters.FormatStringParser.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="color-map" type="xs:string">
            <xs:annotation>
                <xs:documentation>
                    The color-map attribute allows for a comma delimited list of colors to be used for different levels.
                    The
                    format is level-name:color-name.

                    Valid Levels; severe, fatal, error, warn, warning, info, debug, trace, config, fine, finer, finest

                    Valid Colors; black, green, red, yellow, blue, magenta, cyan, white, brightblack, brightred,
                    brightgreen,
                    brightblue, brightyellow, brightmagenta, brightcyan, brightwhite
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="customFormatterType">
        <xs:annotation>
            <xs:documentation>
                <![CDATA[
                Defines a formatter to be used to format log messages.

                Note that most log records are formatted in the printf format. Formatters may require invocation of org.jboss.logmanager.ExtLogRecord#getFormattedMessage() for the message to be properly formatted.
                ]]>
            </xs:documentation>
        </xs:annotation>
        <xs:all>
            <xs:element name="properties" type="propertiesType" minOccurs="0"/>
        </xs:all>
        <xs:attribute name="module" type="xs:string" use="required"/>
        <xs:attribute name="class" type="xs:string" use="required"/>
    </xs:complexType>

    <xs:complexType name="namedFormatterType">
        <xs:annotation>
            <xs:documentation>
                The name of a defined formatter that will be used to format the log message.
            </xs:documentation>
        </xs:annotation>
        <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>

    <xs:complexType name="syslogFormatterType">
        <xs:annotation>
            <xs:documentation>
                Defines a formatter.
            </xs:documentation>
        </xs:annotation>
        <xs:choice minOccurs="1" maxOccurs="1">
            <xs:element name="syslog-format" type="syslogFormatType" maxOccurs="1"/>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="syslogFormatType">
        <xs:annotation>
            <xs:documentation>
                Formats the log message according to the RFC specification.
            </xs:documentation>
        </xs:annotation>
        <xs:attribute name="syslog-type" use="required">
            <xs:simpleType>
                <xs:restriction base="xs:token">
                    <xs:enumeration value="RFC5424">
                        <xs:annotation>
                            <xs:documentation>
                                Formats the message according the the RFC-5424 specification
                                (http://tools.ietf.org/html/rfc5424#section-6)
                            </xs:documentation>
                        </xs:annotation>
                    </xs:enumeration>
                    <xs:enumeration value="RFC3164">
                        <xs:annotation>
                            <xs:documentation>
                                Formats the message according the the RFC-3164 specification
                                (http://tools.ietf.org/html/rfc3164#section-4.1)
                            </xs:documentation>
                        </xs:annotation>
                    </xs:enumeration>
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
    </xs:complexType>

</xs:schema>