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 adserver        = "http://art-decor.org/ns/art-decor-server" at "../api/api-server-settings.xqm";

declare namespace http                  = "http://expath.org/ns/http-client";
declare variable $strDecorServicesURL         := adserver:getServerURLServices();

let $searchString               := if (request:exists()) then (request:get-parameter('searchString',())) else ('lich')
let $projectPrefix              := if (request:exists()) then (request:get-parameter('project',())) else ('demo1-')
(:normally we only want repository valueSets, but when we are looking for a prototype, we want to include valueSets from our own project:)
let $includeLocal               := if (request:exists()) then (request:get-parameter('includelocal','false')='true') else (true())

(:let $searchString               := '2.16.840.1.113883.1.11.1':)
(:let $searchString               := 'administrative':)
(:let $projectPrefix              := 'CR-BIO-':)
(:let $includelocal               := false():)

let $decor                      := $get:colDecorData//decor[project/@prefix=$projectPrefix]

let $buildingBlockRepositories  := 
    if ($includeLocal) then (
        $decor/project/buildingBlockRepository[empty(@format)] | 
        $decor/project/buildingBlockRepository[@format='decor'] | 
        <buildingBlockRepository url="{adserver:getServerURLServices()}" ident="{$projectPrefix}" format="decor"/>
    )
    else (
        $decor/project/buildingBlockRepository[empty(@format)] | 
        $decor/project/buildingBlockRepository[@format='decor']
    )
let $luceneQuery                := 
    <query>
        <bool>
        {
            for $term in tokenize(lower-case(normalize-space($searchString)),'\s')
            return
                <wildcard occur="must">{concat('*', $term, '*')}</wildcard>
        }
        </bool>
    </query>
let $luceneOptions              := art:getSimpleLuceneOptions()

let $result                     := 
    for $repository in $buildingBlockRepositories
    let $repourl                := $repository/@url
    let $repoident              := $repository/@ident
    let $cachedProject          := 
        if ($repourl = $strDecorServicesURL) then
            art:getDecorByPrefix($repoident)
        else (
            $get:colDecorCache//cacheme[@bbrurl = $repourl][@bbrident = $repoident]
        )
    return
    <repositoryList url="{$repourl}" ident="{$repoident}">
    {
        if ($cachedProject) then (
            attribute cachedProject {'true'},
            $cachedProject//valueSet[@id = $searchString] | 
            $cachedProject//valueSet[@id][ft:query(@name, $luceneQuery, $luceneOptions)] |
            $cachedProject//valueSet[@id][ft:query(@displayName, $luceneQuery, $luceneOptions)]
        )
        else (
            attribute cachedProject {'false'},
            let $service-uri    := xs:anyURI(concat($repourl,'/SearchValueSet?searchString=',encode-for-uri($searchString),'&amp;prefix=',$repoident))
            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]//valueSet[@id]
        )
        
    }
    </repositoryList>

return
<result count="{count($result//valueSet)}" search="{$searchString}" includelocal="{$includeLocal}">
{
    for $objects in $result//valueSet
    let $id             := $objects/(@id|@ref)
    group by $id
    order by $objects[1]/@name
    return
        <valueSet uuid="{util:uuid()}" id="{$id}">
        {
            if (count($decor/terminology/valueSet[@ref=$id]) > 0) then attribute alreadyrefed {'true'} else (),
            for $object in $objects
            order by $object/@effectiveDate descending
            return
                <valueSet uuid="{util:uuid()}">
                {
                    $object/ancestor::repositoryList/@url,
                    $object/ancestor::repositoryList/@ident,
                    $object/(@* except (@uuid|@url|@ident))
                }
                </valueSet>
        }
        </valueSet>
}
</result>