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

let $request                := if (request:exists()) then request:get-data()/issue else ()
let $action                 := if (request:exists()) then request:get-parameter('action',()) else ()

(:let $request :=
        <issue id="2.16.840.1.113883.2.4.6.99.1.77.6.5" priority="N" displayName="test" type="RFC">
            <object id="2.16.840.1.113883.2.4.6.99.1.77.2.20000" type="DE" effectiveDate="2010-09-24"/>
            <tracking effectiveDate="2012-01-19T13:36:40.291+01:00" statusCode="open">
                <author id="2">Gerrit Boers</author>
                <desc language="nl-NL">dfbsdfg<b>sadfgdsfg</b>
                    <sub>d</sub>
                </desc>
            </tracking>
        </issue>:)
let $issueId                := $request/@id
let $existingIssue          := $get:colDecorData//issue[@id=$issueId]
let $decor                  := $existingIssue/ancestor::decor
let $prefix                 := $decor/project/@prefix
let $currentUser            := get:strCurrentUserName()
let $updateAuthorName       := try {aduser:getUserDisplayName($currentUser)} catch * {$currentUser}

return
<response>
{
    if (not($existingIssue)) then (
    ) else
    if ($action='update-displayname') then (
        update value $existingIssue/@displayName with $request/@displayName
    ) else
    if ($action='update-type') then (
        update value $existingIssue/@type with $request/@type
    )
    else (
        let $issueAuthorId          := $request/tracking[@effectiveDate=min($request/tracking/xs:dateTime(@effectiveDate))]/author[1]/@id
        let $issueAuthorUserName    := $decor/project/author[@id=$issueAuthorId]/@username
        let $issueAssignedId        := $request/assignment[@effectiveDate=max($request/assignment/xs:dateTime(@effectiveDate))]/@to
        let $issueAssignedUserName  := $decor/project/author[@id=$issueAssignedId]/@username
        
        let $issueLastTracking      := $request/tracking[@effectiveDate=max($request/tracking/xs:dateTime(@effectiveDate))]
        
        let $by                     := $decor/project/author[@id=$issueLastTracking/author[1]/@id]/@username
        let $by                     := if ($by) then $by[1] else get:strCurrentUserName()
        let $timeStamp              := $issueLastTracking/@effectiveDate
        let $timeStamp              := if ($timeStamp) then ($timeStamp) else substring-before(xs:string(current-dateTime()), '.')
        let $language               := $issueLastTracking/desc/@language
        let $language               := if ($language) then ($language) else $decor/project/@defaultLanguage
        
        let $newIssue       :=
            <issue id="{$issueId}" priority="{$request/@priority}" displayName="{$request/@displayName}" type="{$request/@type}">
            {
                for $object in $request/object
                return
                    <object id="{$object/@id}" type="{$object/@type}">
                    {
                        if (string-length($object/@effectiveDate)>0) then ($object/@effectiveDate) else (),
                        if (string-length($object/@name)>0) then ($object/@name) else ()
                    }
                    </object>,
                for $event in $request/tracking|$request/assignment
                order by xs:dateTime($event/@effectiveDate) ascending
                return
                    if ($event[self::tracking]) then (
                        <tracking effectiveDate="{$event/@effectiveDate}" statusCode="{$event/@statusCode}">
                        {
                            if (string-length($event/@labels)>0) then ($event/@labels) else (), 
                            $event/author,
                            if ($event[edit]) then (
                                let $updateAuthor       := $decor/project/author[@username=$currentUser]
                                
                                return
                                <author>
                                {
                                    if ($updateAuthor) then ($updateAuthor/@id) else ()
                                    ,
                                    attribute effectiveDate {substring(string(current-dateTime()),1,19)}
                                    ,
                                    $updateAuthorName
                                }
                                </author>
                            )
                            else ()
                        }
                        {
                            for $desc in $event/desc
                            return
                                art:parseNode($desc)
                        }
                        </tracking>
                    )
                    else if ($event[self::assignment]) then
                        <assignment to="{$event/@to}" name="{$event/@name}" effectiveDate="{$event/@effectiveDate}">
                        {
                            if (string-length($event/@labels)>0) then ($event/@labels) else (),
                            $event/author,
                            if ($event[edit]) then (
                                let $updateAuthor       := $decor/project/author[@username=$currentUser]
                                
                                return
                                <author>
                                {
                                    if ($updateAuthor) then ($updateAuthor/@id) else ()
                                    ,
                                    attribute effectiveDate {substring(string(current-dateTime()),1,19)}
                                    ,
                                    $updateAuthorName
                                }
                                </author>
                            )
                            else ()
                        }
                        {
                            for $desc in $event/desc
                            return
                                art:parseNode($desc)
                        }
                        </assignment>
                    else ()
            }
            </issue>
        
        return (
            update replace $existingIssue with $newIssue
            ,
            for $authorUserName in $decor/project/author/@username
            let $userAutoSubscribes := aduser:userHasIssueAutoSubscription($authorUserName, $prefix, $issueId, $newIssue/object/@type, $issueAuthorUserName[1], $issueAuthorUserName[1])
            return
                if ($userAutoSubscribes) then
                    aduser:setUserIssueSubscription($authorUserName, $issueId)
                else ()
        )
    )
}
</response>