<?xml version="1.0" encoding="UTF-8"?>
<!--
  KodeMed COM DLL — GetResults() XML serialisation (canonical) — v1.0

  XML wire shape returned by `IKodeMed.GetResults()` when the partner
  configures OutputFormat=Xml. Describes the SAME data model as the JSON
  variant (`GetResults-1.0.schema.json`) — same field names, same nesting,
  same uniformity invariants (#640). The DLL `XmlSerializer` round-trips
  this shape; the C# `KodeMed.Interface.Models.CodingResults` class is
  the matching binding.

  Conventions:
    - camelCase element + attribute names. Matches the JSON variant so
      partners that read both formats see the same identifiers.
    - sessionId / instanceId / eventType / occurredAt are top-level
      attributes (single-value envelope metadata, XML-idiomatic).
    - cases / stats are sub-elements (carry structured content).
    - Case data XML is embedded as CDATA inside the data element so the
      pure SPIGES Fall payload travels intact without re-escaping —
      partners extract and validate it against SPIGES-1.5.xsd directly.
    - Model-separation invariant (#640): NEVER inject grouper output
      inside the SPIGES Fall element. Grouper output lives only in the
      codingResult element next to data, never inside it.
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="https://schemas.kodemed.ch/dll_com/GetResults-1.0"
           xmlns="https://schemas.kodemed.ch/dll_com/GetResults-1.0"
           elementFormDefault="qualified"
           version="1.0">

  <!-- ───────────────────────── Root ───────────────────────── -->

  <xs:element name="codingResults" type="CodingResultsType">
    <xs:annotation>
      <xs:documentation>
        Root element of the COM `GetResults()` XML return. Single
        instance per call. Matches the JSON-variant top-level object
        of `GetResults-1.0.schema.json`.
      </xs:documentation>
    </xs:annotation>
  </xs:element>

  <xs:complexType name="CodingResultsType">
    <xs:sequence>
      <xs:element name="cases" type="CasesType"/>
      <xs:element name="stats" type="StatsType" minOccurs="0"/>
      <!-- customProperties is a JSON-only extension point (the C# model
           marks it [XmlIgnore]); it never travels in the XML transport, so
           it is intentionally absent here. See the JSON schema + MD. -->
    </xs:sequence>
    <xs:attribute name="sessionId"  type="IdentifierType"        use="required"/>
    <xs:attribute name="instanceId" type="OpaqueIdentifierType"  use="optional"/>
    <xs:attribute name="eventType"  type="EventTypeType"         use="required"/>
    <xs:attribute name="occurredAt" type="xs:dateTime"           use="required"/>
  </xs:complexType>

  <!-- ───────────────────────── Cases array ───────────────────────── -->

  <xs:complexType name="CasesType">
    <xs:sequence>
      <xs:element name="case" type="CaseResultType" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="CaseResultType">
    <xs:annotation>
      <xs:documentation>
        One coded case. Mirrors `_common/CaseResult.schema.json` —
        carries the case data (data + format + ...) AND the grouper
        result (codingResult), with the SPIGES XML pure inside the
        data element (no GrouperResult injection — #640 model-separation).
      </xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element name="data" type="xs:string">
        <xs:annotation>
          <xs:documentation>
            Raw case-data XML payload (SPIGES Fall or BFS variant).
            Embedded as CDATA so the inner XML travels intact. Partners
            extract this string and validate it against SPIGES-1.5.xsd
            independently.
          </xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="codingResult" type="CodingResultType"/>
    </xs:sequence>
    <xs:attribute name="format"        type="FormatType" use="required"/>
    <xs:attribute name="schemaVersion" type="xs:string"  use="optional"/>
    <xs:attribute name="dataHash"      type="xs:string"  use="optional"/>
  </xs:complexType>

  <!-- ───────────────────────── CodingResult ───────────────────────── -->

  <xs:complexType name="CodingResultType">
    <xs:annotation>
      <xs:documentation>
        Full grouper output for one case. Mirrors
        `_common/CodingResult.schema.json` field-for-field.
      </xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <!--
        Nullable-on-Java fields cannot be xs:attribute when the binding
        is System.Xml.Serialization in .NET (Nullable<T> + XmlAttribute
        is unsupported in that runtime). The Java/C# binding emits them
        as elements; the XSD matches by declaring them as
        xs:element minOccurs="0" so the round-trip stays valid. The
        cross-format uniformity check (R9 in
        scripts/test/test-schemas-uniformity.py) verifies the element
        + attribute NAMES align with the JSON schema 1:1 — element-vs-
        attribute is implementation detail for this XSD-XML pair.
      -->
      <xs:element name="pccl"                type="xs:integer"  minOccurs="0"/>
      <xs:element name="costWeight"          type="xs:decimal"  minOccurs="0"/>
      <xs:element name="baseCostWeight"      type="xs:decimal"  minOccurs="0"/>
      <xs:element name="effectiveCostWeight" type="xs:decimal"  minOccurs="0"/>
      <xs:element name="los"                 type="xs:integer"  minOccurs="0"/>
      <xs:element name="ltp"                 type="xs:integer"  minOccurs="0"/>
      <xs:element name="htp"                 type="xs:integer"  minOccurs="0"/>
      <xs:element name="alos"                type="xs:decimal"  minOccurs="0"/>
      <xs:element name="dayRate"             type="xs:decimal"  minOccurs="0"/>
      <xs:element name="transferDiscount"    type="xs:boolean"  minOccurs="0"/>
      <xs:element name="groupingSuccess"     type="xs:boolean"  minOccurs="0"/>
      <xs:element name="groupedAt"           type="xs:dateTime" minOccurs="0"/>
      <xs:element name="diagnoses"   type="DiagnosesType"/>
      <xs:element name="procedures"  type="ProceduresType"/>
      <xs:element name="supplements" type="SupplementsType" minOccurs="0"/>
      <xs:element name="warnings"    type="WarningsType"    minOccurs="0"/>
      <xs:element name="flags"       type="FlagsType"       minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="caseId"              type="OpaqueIdentifierType" use="required"/>
    <xs:attribute name="tariff"              type="TariffType"           use="optional"/>
    <xs:attribute name="drg"                 type="xs:string"            use="optional"/>
    <xs:attribute name="drgDescription"      type="xs:string"            use="optional"/>
    <xs:attribute name="mdc"                 type="xs:string"            use="optional"/>
    <xs:attribute name="partition"           type="xs:string"            use="optional"/>
    <xs:attribute name="grouperVersion"      type="xs:string"            use="optional"/>
    <xs:attribute name="grouperStatus"       type="xs:string"            use="optional"/>
    <xs:attribute name="groupingError"       type="xs:string"            use="optional"/>
  </xs:complexType>

  <xs:complexType name="DiagnosesType">
    <xs:sequence>
      <xs:element name="diagnosis" type="DiagnosisType" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="DiagnosisType">
    <xs:attribute name="code"            type="xs:string"      use="required"/>
    <xs:attribute name="catalog"         type="DiagCatalogType" use="required"/>
    <xs:attribute name="isHauptdiagnose" type="xs:boolean"     use="optional"/>
    <xs:attribute name="isDagger"        type="xs:boolean"     use="optional"/>
    <xs:attribute name="isAsterisk"      type="xs:boolean"     use="optional"/>
    <xs:attribute name="isExclamation"   type="xs:boolean"     use="optional"/>
    <xs:attribute name="zusatz"          type="xs:string"      use="optional"/>
    <xs:attribute name="poa"             type="xs:string"      use="optional"/>
  </xs:complexType>

  <xs:complexType name="ProceduresType">
    <xs:sequence>
      <xs:element name="procedure" type="ProcedureType" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="ProcedureType">
    <xs:attribute name="code"        type="xs:string"   use="required"/>
    <xs:attribute name="catalog"     type="ProcCatalogType" use="required"/>
    <xs:attribute name="performedAt" type="xs:dateTime" use="optional"/>
    <xs:attribute name="laterality"  type="LateralityType" use="optional"/>
  </xs:complexType>

  <xs:complexType name="SupplementsType">
    <xs:sequence>
      <xs:element name="supplement" type="SupplementType" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="SupplementType">
    <!--
      #640 CRITICAL #4b — `count` is xs:element (NOT xs:attribute) because
      the C# binding uses `int?` (Nullable<int>), and System.Xml.Serialization
      refuses Nullable<T> on XmlAttribute (same constraint that drove the
      2026-06-02 audit fix for the case-level nullable fields). The C# side
      already declares [XmlElement("count")] on SupplementResult.Count
      (KodeMed.Interface/Models/CodingResults.cs:580) — XSD now matches.
      Pre-audit drift: XML emitted by the DLL was rejected by this XSD.
    -->
    <xs:sequence>
      <xs:element name="count"       type="xs:integer" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="code"        type="xs:string"  use="required"/>
    <xs:attribute name="description" type="xs:string"  use="optional"/>
    <xs:attribute name="amount"      type="xs:decimal" use="required"/>
  </xs:complexType>

  <xs:complexType name="WarningsType">
    <xs:sequence>
      <xs:element name="warning" type="WarningType" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="WarningType">
    <xs:attribute name="code"     type="xs:string"     use="required"/>
    <xs:attribute name="message"  type="xs:string"     use="required"/>
    <xs:attribute name="severity" type="SeverityType"  use="optional"/>
  </xs:complexType>

  <xs:complexType name="FlagsType">
    <xs:sequence>
      <xs:element name="flag" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <!-- ───────────────────────── Stats (diagnostic) ───────────────────────── -->

  <xs:complexType name="StatsType">
    <xs:sequence>
      <xs:element name="warnings" type="StringListType" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="startedAt"       type="xs:dateTime" use="optional"/>
    <xs:attribute name="finishedAt"      type="xs:dateTime" use="optional"/>
    <xs:attribute name="durationMs"      type="xs:integer"  use="optional"/>
    <xs:attribute name="casesProcessed"  type="xs:integer"  use="optional"/>
    <xs:attribute name="diagnosesCount"  type="xs:integer"  use="optional"/>
    <xs:attribute name="treatmentsCount" type="xs:integer"  use="optional"/>
    <xs:attribute name="sitesCount"      type="xs:integer"  use="optional"/>
    <xs:attribute name="enterpriseId"    type="xs:integer"  use="optional"/>
    <xs:attribute name="spiGesVersion"   type="xs:string"   use="optional"/>
    <xs:attribute name="success"         type="xs:boolean"  use="optional"/>
    <xs:attribute name="errorMessage"    type="xs:string"   use="optional"/>
  </xs:complexType>

  <xs:complexType name="StringListType">
    <xs:sequence>
      <xs:element name="item" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <!-- ───────────────────────── Shared types ─────────────────────────
       Mirror the constraints from the matching _common/*.schema.json
       files. Drift between the JSON and XML variants is caught by the
       cross-format uniformity check in scripts/test/test-schemas-uniformity.py.
  -->

  <xs:simpleType name="IdentifierType">
    <xs:annotation>
      <xs:documentation>Server-generated UUID (matches _common/Identifier.schema.json).</xs:documentation>
    </xs:annotation>
    <xs:restriction base="xs:string">
      <xs:pattern value="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="OpaqueIdentifierType">
    <xs:annotation>
      <xs:documentation>Partner-controlled non-blank string up to 100 chars (matches _common/OpaqueIdentifier.schema.json).</xs:documentation>
    </xs:annotation>
    <xs:restriction base="xs:string">
      <xs:minLength value="1"/>
      <xs:maxLength value="100"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="EventTypeType">
    <xs:annotation>
      <xs:documentation>
        Outcome of the session (matches _common/EventType.schema.json
        subset valid for GetResults: case.coded, case.discarded,
        session.expired). The legacy CodingAction.Cancelled / Timeout /
        Error map onto these via the C# refactor.
      </xs:documentation>
    </xs:annotation>
    <xs:restriction base="xs:string">
      <xs:enumeration value="case.coded"/>
      <xs:enumeration value="case.discarded"/>
      <xs:enumeration value="session.expired"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="FormatType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="spiges"/>
      <xs:enumeration value="bfs"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="TariffType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="SWISSDRG"/>
      <xs:enumeration value="TARPSY"/>
      <xs:enumeration value="STREHA"/>
      <xs:enumeration value="SPLG"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="DiagCatalogType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="ICD-10-GM"/>
      <xs:enumeration value="ICD-10-WHO"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="ProcCatalogType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="CHOP"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="LateralityType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="L"/>
      <xs:enumeration value="R"/>
      <xs:enumeration value="B"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="SeverityType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="INFO"/>
      <xs:enumeration value="WARNING"/>
      <xs:enumeration value="ERROR"/>
    </xs:restriction>
  </xs:simpleType>

</xs:schema>
