xquery version "3.0";
(:
    ART-DECOR® STANDARD COPYRIGHT AND LICENSE NOTE
    Copyright © ART-DECOR Expert Group and ART-DECOR Open Tools GmbH
    see https://docs.art-decor.org/copyright and https://docs.art-decor.org/licenses

    This file is part of the ART-DECOR® tools suite.
:)
import module namespace get     = "http://art-decor.org/ns/art-decor-settings" at "art-decor-settings.xqm";
import module namespace art     = "http://art-decor.org/ns/art" at "art-decor.xqm";
(:import module namespace getf    = "http://art-decor.org/ns/fhir-settings" at "../../fhir/3.0/api/fhir-settings.xqm";:)

declare namespace http          = "http://expath.org/ns/http-client";
declare namespace f             = "http://hl7.org/fhir";

let $projectPrefix          := if (request:exists()) then request:get-parameter('project',()) else ('demo1-')
let $projectVersion         := if (request:exists()) then request:get-parameter('version',()) else ()

let $decor                  := art:getDecorByPrefix($projectPrefix)

let $decorbbrs              := $decor/project/buildingBlockRepository[@format='fhir']

(:
    Hard coded Accept header may turn out tricky, but relying on one particular FHIR server for this variable is even more tricky
:)
let $requestHeaders         := 
    <headers>
        <!--<header name="Accept" value="{$getf:CT_FHIR_XML}"/>-->
        <header name="Accept" value="application/fhir+xml"/>
        <header name="Content-Type" value="text/xml"/>
        <header name="Cache-Control" value="no-cache"/>
        <header name="Max-Forwards" value="1"/>
    </headers>

return
    <return>
    {
        (:<structuredefinitionAssociation baseref="1" ref="Nictiz-bgz-AllergyIntolerance" displayName="AllergyIntolerance"/>:)
        (:for $reference in $decor/rules/structuredefinitionAssociation
        let $url    := concat($restURIs[@id=$reference/@baseref][1],'StructureDefinition/',$reference/@ref)
        return
            element {$reference/name()} {
                $reference/@*,
                attribute url {$url}
            }:)
            
        for $structuredefinitions in $decor/rules/structuredefinition
        let $rf     := $structuredefinitions/@referencedFrom
        let $lbbr   := ($decorbbrs[@ident = $structuredefinitions/@referencedFrom])[1]
        group by $rf
        return
            <repository id="{util:uuid()}" ident="{$lbbr/@ident}" url="{$lbbr/@url}" displayName="{if ($lbbr/@displayName) then $lbbr/@displayName else $lbbr/@ident}">
            {
                for $sd in $structuredefinitions
                return
                    <structuredefinition>
                    {
                        $sd/@*,
                        (: all https://stu3.simplifier.net/medikationsplanplus/StructureDefinition?_format=application/fhir+xml :)
                        
                        if (true()) then (
                            try {
                                let $service-uri    := $sd/@publicationUrl
                                let $requestHeaders := 
                                    <http:request method="GET" href="{$service-uri}">
                                        <http:header name="Content-Type" value="text/xml"/>
                                        <http:header name="Cache-Control" value="no-cache"/>
                                        <http:header name="Max-Forwards" value="1"/>
                                    </http:request>
                               let $server-response        := http:send-request($requestHeaders)
                               return (
                                   $server-response[2]//f:StructureDefinition, $sd/concept
                               )
                            } catch * { () }
                        ) else (
                            $sd/f:StructureDefinition
                        )
                        
                        (:<concept ref="2.16.840.1.113883.3.1937.99.62.3.2.1" effectiveDate="2012-05-30T11:32:36" elementId="2.16.840.1.113883.3.1937.99.62.3.11.12.1"/>:)
                        (:for $concept in $sd/concept
                        let $conceptId      := $concept/@ref
                        let $conceptEd      := $concept/@effectiveDate
                        let $elementId      := $concept/@elementId
                        let $elementPath    := $concept/@elementPath
                        let $theConcept     := art:getConcept($conceptId, $conceptEd)
                        let $theOriginalConcept := art:getOriginalForConcept($theConcept)
                        let $conceptEd      := $theConcept/@effectiveDate
                        let $theDataset     := $theConcept/ancestor::*:dataset
                        let $datasetId      := $theDataset/@id
                        let $datasetEd      := $theDataset/@effectiveDate
                        return
                            <concept>
                            {
                                $conceptId, $conceptEd, $elementId, $elementPath,
                                attribute refdisplay {art:getNameForOID($elementId, (), ())},
                                attribute datasetId {$datasetId},
                                attribute datasetEffectiveDate {$datasetEd},
                                attribute prefix {$theConcept/ancestor::decor/project/@prefix},
                                <path>
                                {
                                    for $ancestor in $theConcept/ancestor::concept
                                    return
                                        concat(art:getOriginalForConcept($ancestor)/name[1]/text(), ' / ')
                                }
                                </path>,
                                $theOriginalConcept/name
                            }
                            </concept>:)
                    }
                    </structuredefinition>
            }
            </repository>
    }
    </return>