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 xs                = "http://www.w3.org/2001/XMLSchema";
declare namespace xforms            = "http://www.w3.org/2002/xforms";
declare namespace http              = "http://expath.org/ns/http-client";

declare %private function local:groupPrototypeListByVersion($list as element()) as element() {

let $tmp :=
    for $template in $list/template[@id]
    let $id     := $template/@id
    let $name   := $template/@name
    group by $id, $name
    order by $name
    return
        <template id="{$id}">
        {
            for $version in $template
            order by $version/@effectiveDate descending
            return
                <template>
                    {
                        $version/(@* except @isClosed),
                        attribute isClosed {$version/@isClosed='true'},
                        attribute sortname {if (string-length($version/@displayName)>0) then $version/@displayName else $version/@name},
                        $version/desc,
                        $version/classification
                    }
                </template>

        }
        </template>

let $result :=
    for $template in $tmp
    return
        if (count($template/template)>1) 
        then 
            <template>
            {
                $template/template[1]/(@* except @effectiveDate),
                attribute hasMultipleVersions {'true'},
                $template/template[1]/desc,
                $template/template[1]/classification,
                $template/*
            }
            </template>
            
        else
            $template/template
    
return
    <prototypeList>
    {
        $list/@*,
        $result
    }
    </prototypeList>
    
};


let $projectPrefix      := request:get-parameter('project','')
let $art-languages      := art:getArtLanguages()
(:let $projectPrefix := 'demo1-':)
let $repositories       := $get:colDecorData//project[@prefix=$projectPrefix]/buildingBlockRepository[empty(@format)] |
                           $get:colDecorData//project[@prefix=$projectPrefix]/buildingBlockRepository[@format='decor']
let $schemaTypes        := art:getDecorTypes()//TemplateTypes/enumeration

let $prototypeList      :=
    for $repository in $repositories
    let $format         := if ($repository[@format]) then $repository/@format else 'decor'
    let $cachedProject  := $get:colDecorCache//decor[project/@prefix=$repository/@ident][@deeplinkprefixservices=$repository/@url]
    return
        <prototypeList url="{$repository/@url}" ident="{$repository/@ident}" format="{$format}">
        {
            if ($cachedProject) then (
                for $template in $cachedProject/rules/template
                order by $template/@displayName, $template/@effectiveDate
                return 
                    <template>{
                        $template/@id,
                        $template/@ref,
                        $template/@name,
                        $template/@displayName,
                        $template/@statusCode,
                        $template/@effectiveDate,
                        $template/@officialReleaseDate,
                        $template/@expirationDate,
                        $template/@versionLabel,
                        $template/@isClosed,
                        $template/@canonicalUri,
                        $template/@lastModifiedDate,
                        attribute url {$repository/@url},
                        attribute ident {$repository/@ident},
                        for $node in $template/desc
                        return art:parseNode($node)
                        ,
                        $template/classification
                    }</template>
            )
            (: http() call as last resort. :)
            else (
                try {
                    let $service-uri    := xs:anyURI(concat($repository/@url,'TemplateIndex?format=xml&amp;prefix=',$repository/@ident))
                    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]/template
                }
                catch * {()}
            )
        }
        </prototypeList>
    
let $ownProjectTemplateList :=
    <prototypeList url="{adserver:getServerURLServices()}" ident="{$projectPrefix}">
    {
        (: add all your project's templates :)
        for $template in $get:colDecorData//decor[project[@prefix=$projectPrefix]]/rules/template[@id]
        return
        <template>
        {
                $template/@*,
                attribute own {'true'},
                $template/classification,
                for $desc in $template/desc
                return
                    art:serializeNode($desc)
         }
         </template>

    }
    </prototypeList>

(: group prototype templates by versions :)
let $allprototypes :=
    for $p in $prototypeList|$ownProjectTemplateList
    return local:groupPrototypeListByVersion($p)

return
<prototypeList>
{
    for $template in $allprototypes/template
    let $type := if ($template/@own) then ('zzzown') else if ($template/classification[1]/@type) then $template/classification[1]/@type else ('notype')
    group by $type 
    return
        <class type="{$type}">
        {
            if ($type="zzzown") then (
                for $element in art:getFormResourcesKey('art',$art-languages,'project-templates')
                return
                    <label language="{$element/@xml:lang}">{$element/node()}</label>
            )
            else ( 
                for $label in $schemaTypes[@value=$type]/label
                return
                <label language="{$label/@language}">{$label/text()}</label>
            )
            ,
            for $templateType in $template 
            return
                <template>
                {
                    $templateType/(@* except (@url|@ident)),
                    attribute url {$templateType/ancestor::prototypeList/@url},
                    attribute ident {$templateType/ancestor::prototypeList/@ident},
                    $templateType/desc,
                    $templateType/template
                }
                </template>
        }
        </class>
}
</prototypeList>