xquery version "1.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 templ       = "http://art-decor.org/ns/decor/template" at "../api/api-decor-template.xqm";
import module namespace adserver    = "http://art-decor.org/ns/art-decor-server" at "../api/api-server-settings.xqm";

declare %private function local:getProjectName($object as element(), $language as xs:string) as xs:string? {
    let $projectNames   := $object/ancestor-or-self::decor/project/name
    
    return if ($projectNames[@language = $language]) then $projectNames[@language = $language] else ($projectNames[1])
};

let $id                         := if (request:exists()) then request:get-parameter('id',())[string-length()>0]             else ('2.16.840.1.113883.2.4.3.11.60.40.1.12.2.2')
let $effectiveDate              := if (request:exists()) then request:get-parameter('effectiveDate',())[string-length()>0]  else ('2017-09-04T00:00:00')

let $theConcept                 := art:getConcept($id, $effectiveDate)
let $effectiveDate              := if (string-length($effectiveDate)=0) then $theConcept/@effectiveDate else $effectiveDate

let $language                   := if (request:exists()) then request:get-parameter('language',()) else ('nl-NL')
let $language                   := if (string-length($language)>0) then $language else ($theConcept/ancestor::decor/project/@defaultLanguage)[1]

(: overly complex selection but eXist-db performs a lot less otherwise :)
let $searchsetinherit           := $get:colDecorData//inherit[@ref = $id]
let $searchsetinherit           := $searchsetinherit[@effectiveDate = $effectiveDate]
let $searchsetcontains          := $get:colDecorData//contains[@ref = $id]
let $searchsetcontains          := $searchsetcontains[@flexibility = $effectiveDate]
let $searchset                  := $searchsetinherit[not(ancestor::history)]/parent::concept | $searchsetcontains[not(ancestor::history)]/parent::concept

let $concepts                   :=
    for $concept in $searchset
    let $language               := $concept/ancestor::decor/project/@defaultLanguage
    return
        <dataset>
        {
            $concept/ancestor::dataset/(@id|@effectiveDate|@versionLabel),
            attribute prefix {$concept/ancestor::decor/project/@prefix},
            attribute projectName {$concept/ancestor::decor/project/name[1]},
            attribute conceptId {$concept/@id},
            attribute conceptEffectiveDate {$concept/@effectiveDate},
            $concept/ancestor::dataset/name
        }
            <path>
            {
                for $ancestor in $concept/ancestor::concept
                return
                    concat(art:getOriginalForConcept($ancestor)/name[@language=$language][1]/text(), ' / ')
            }
            </path>
        </dataset>
let $searchset                  := $theConcept

let $transactions               :=
    for $concept in $searchset
    let $datasetId              := $concept/ancestor::dataset/@id
    let $datasetEffectiveDate   := $concept/ancestor::dataset/@effectiveDate
    let $trxs   := art:getTransactionsByDataset($datasetId, $datasetEffectiveDate)
    for $trxcpt in ($trxs/representingTemplate/concept[@ref=string($concept/@id)] | $trxs/representingTemplate/concept[@ref=string($concept/@ref)])
    return
        <transaction>
        {
            $trxcpt/../../(@id|@effectiveDate|@statusCode|@versionLabel),
            attribute prefix {$concept/ancestor::decor/project/@prefix},
            attribute projectName {local:getProjectName($concept, $language)},
            attribute datasetId {$datasetId},
            attribute datasetEffectiveDate {$datasetEffectiveDate},
            attribute minimumMultiplicity {art:getMinimumMultiplicity($trxcpt)},
            attribute maximumMultiplicity {art:getMaximumMultiplicity($trxcpt)},
            $trxcpt/@conformance,
            attribute isMandatory {$trxcpt/@isMandatory='true'},
            $trxcpt/../../name, (:transaction name:)
            for $datasetName in $concept/ancestor::dataset/name
            return
                <datasetName>
                {
                    $datasetName/@*,
                    $datasetName/../@versionLabel,
                    $datasetName/text() 
                }
                </datasetName>
        }
        {   
            $trxcpt/condition
        }
            <path>
            {
                for $ancestor in $concept/ancestor::concept
                return
                    concat(art:getOriginalForConcept($ancestor)/name[@language=$language][1]/text(), ' / ')
            }
            </path>
        </transaction>

(:<concept ref="2.16.840.1.113883.2.4.3.11.60.101.2.1.10000" effectiveDate="2013-03-25T21:46:30" elementId="2.16.840.1.113883.2.4.3.11.60.101.9.1"/>:)
let $templateAssociations       := $get:colDecorData//templateAssociation/concept[@ref = $searchset/@id][@effectiveDate = $searchset/@effectiveDate]
let $templates                  := 
    for $templateAssociation in $templateAssociations
    let $elementId              := $templateAssociation/@elementId
    let $templateId             := $templateAssociation/parent::*/@templateId
    let $templateEffectiveDate  := $templateAssociation/parent::*/@effectiveDate
    let $prefixAssociation      := $templateAssociation/ancestor::decor/project/@prefix
    (:let $template               := $templateAssociation/ancestor::decor//template[@id = $templateId][@effectiveDate = $templateEffectiveDate]:)
    let $template               := $get:colDecorData//template[@id = $templateId] | $get:colDecorCache//template[@id = $templateId]
    let $template               := $template[@effectiveDate = $templateEffectiveDate][1]
    (:let $template               := (templ:getTemplateById($templateId, $templateEffectiveDate, $prefixAssociation)/*/template[@id])[1]:)
    let $templateName           := if ($template/@displayName) then $template/@displayName/string() else ($template/@name/string())
    let $targets                := ($template//element[@id=$elementId] | $template//attribute[@id=$elementId])
    return
        for $target in $targets
        return
            <template id="{$templateId}" name="{$templateName}" effectiveDate="{$templateEffectiveDate}" element="{$target/@name}" 
                prefix="{$prefixAssociation}" projectName="{local:getProjectName($templateAssociation, $language)}">
            {
                if ($target/@conformance='NP') then () else (
                    attribute minimumMultiplicity {art:getMinimumMultiplicity($target)}
                )
                ,
                if ($target/@conformance='NP') then () else (
                    attribute maximumMultiplicity {art:getMaximumMultiplicity($target)}
                )
                ,
                $target/@conformance,
                attribute isMandatory {$target/@isMandatory='true'}
            }
            <path>
            {
                string-join(
                    for $ancestor in $target/ancestor-or-self::*[self::element | self::attribute]
                    let $min    := if ($ancestor/@conformance='NP') then () else (art:getMinimumMultiplicity($ancestor))
                    let $max    := if ($ancestor/@conformance='NP') then () else (art:getMaximumMultiplicity($ancestor))
                    let $conf   := if ($ancestor/@isMandatory='true') then ('M') else ($target/@conformance)
                    let $mmc    := string-join((string-join(($min,$max), '…'),$conf),' ')
                    return
                    $ancestor/concat(if (self::attribute) then '@' else (),@name,if (empty($mmc)) then () else concat(' (',$mmc,')'))
                ,' / ')
            }
            </path>
            </template>
return
<usage id="{$id}" effectiveDate="{$effectiveDate}">
{
    $concepts
    ,
    $transactions
    ,
    $templates
}
</usage>


