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.
:)
(: This package consolidates functions previously confined in decor/services and aims to offer them 
   to any package that needs them. The functions here aim to be useful for calling localized strings 
   from xquery.
   
   Call i18n:getMessagesDoc($packageRoot as xs:string) and feed that back into i18n:getMessage(..)
   Example:
        let $docMessages    := i18n:getMessagesDoc('decor/services')
        i18n:getMessage($docMessages,'key')
:)
module namespace i18n                   = "http://art-decor.org/ns/decor/i18n";
import module namespace get             = "http://art-decor.org/ns/art-decor-settings" at "../modules/art-decor-settings.xqm";
import module namespace art             = "http://art-decor.org/ns/art" at "../modules/art-decor.xqm";
import module namespace aduser          = "http://art-decor.org/ns/art-decor-users" at "api-user-settings.xqm";

declare function i18n:getMessage($docMessages as item()*,$key as xs:string) as item()* {
    i18n:getMessage($docMessages,$key,aduser:getUserLanguage(),(),(),(),())
};
declare function i18n:getMessage($docMessages as item()*,$key as xs:string,$language as xs:string) as item()* {
    i18n:getMessage($docMessages,$key,$language,(),(),(),())
};
declare function i18n:getMessage($docMessages as item()*,$key as xs:string,$language as xs:string,$p1 as xs:string?) as item()* {
    i18n:getMessage($docMessages,$key,$language,$p1,(),(),())
};
declare function i18n:getMessage($docMessages as item()*,$key as xs:string,$language as xs:string,$p1 as xs:string?,$p2 as xs:string?) as item()* {
    i18n:getMessage($docMessages,$key,$language,$p1,$p2,(),())
};
declare function i18n:getMessage($docMessages as item()*,$key as xs:string,$language as xs:string,$p1 as xs:string?,$p2 as xs:string?,$p3 as xs:string?) as item()* {
    i18n:getMessage($docMessages,$key,$language,$p1,$p2,$p3,())
};
declare function i18n:getMessage($docMessages as item()*,$key as xs:string,$language as xs:string,$p1 as xs:string?,$p2 as xs:string?,$p3 as xs:string?,$p4 as xs:string?) as item()* {
    let $i18n   := 
        if ($docMessages instance of element(entry)*) then (
            $docMessages[@key = $key]
        ) else 
        if ($docMessages instance of xs:string) then (
            collection(concat($get:root, $docMessages, '/resources'))//entry[@key = $key]
        ) else (
            error(QName('http://art-decor.org/ns/error', 'UnknownParameterType'), 'Parameter $docMessages is of an unknown type. Supported types are xs:string and element(entry)*')
        )
    let $text   := $i18n/text[@language = $language]
    let $text   := if ($text) then $text else $i18n/text[substring(@language, 1, 2) = substring($language, 1, 2)]
    let $text   := if ($text) then $text else $i18n/text[@language = aduser:getUserLanguage()]
    let $text   := if ($text) then $text else $i18n/text[@language = 'en-US']
    let $text   := if ($text) then $text else <text language="{$language}">{concat('NOT FOUND in messages: MESSAGE key=',$key,' p1=%%1 p2=%%2 p3=%%3 p4=%%4')}</text>
    
    (: parsing/serializing costs performance. check if necessary. most is just text :)
    let $hasNodes   := $text[*]
    
    let $tmp1   := if ($hasNodes)  then art:serializeNode($text[1])                                       else $text[1]
    let $tmp2   := if (empty($p1)) then (replace($tmp1, '%%1', ''))                                       else (replace($tmp1, '%%1', $p1))
    let $tmp3   := if (empty($p2)) then (replace($tmp2, '%%2', ''))                                       else (replace($tmp2, '%%2', $p2))
    let $tmp4   := if (empty($p3)) then (replace($tmp3, '%%3', ''))                                       else (replace($tmp3, '%%3', $p3))
    let $tmp5   := if (empty($p4)) then (replace($tmp4, '%%4', ''))                                       else (replace($tmp4, '%%4', $p4))
    let $tmp6   := if ($hasNodes)  then art:parseNode(<text language="{$language}">{$tmp5}</text>)/node() else $tmp5
    
    return $tmp6
};

(:
:   Get REST-i18n.xml for a package
:   - Check <package>/resources/REST-i18n.xml
:   - Local deviations through art-data not implemented (yet?)
:)
declare function i18n:getMessagesDoc($packageRoot as xs:string) as element(entry)* {
    i18n:getMessagesDoc($packageRoot, false())
};
declare %private function i18n:getMessagesDoc($packageRoot as xs:string?, $local as xs:boolean) as element(entry)* {
let $packageRoot            := if (empty($packageRoot)) then 'art' else $packageRoot
return
    if ($local) then 
        collection($get:strArtData)//*[@packageRoot = $packageRoot]/entry
    else (
        collection(concat($get:root,$packageRoot,'/resources'))/*[@packageRoot = $packageRoot]/entry
    )
};