xquery version "3.1";

module namespace san="http://ahiqar.uni-goettingen.de/ns/annotations/save";

import module namespace anno="http://ahiqar.uni-goettingen.de/ns/annotations" at "/db/apps/ahiqar/modules/AnnotationAPI/annotations.xqm";
import module namespace commons="http://ahiqar.uni-goettingen.de/ns/commons" at "/db/apps/ahiqar/modules/commons.xqm";
import module namespace edit="http://ahiqar.uni-goettingen.de/ns/annotations/editorial" at "/db/apps/ahiqar/modules/AnnotationAPI/editorial.xqm";
import module namespace ls="http://ahiqar.uni-goettingen.de/ns/annotations/line-segmentation" at "/db/apps/ahiqar/modules/AnnotationAPI/line-segmentation.xqm";
import module namespace motifs="http://ahiqar.uni-goettingen.de/ns/annotations/motifs" at "/db/apps/ahiqar/modules/AnnotationAPI/motifs.xqm";
import module namespace sedra="http://ahiqar.uni-goettingen.de/ns/annotations/sedra" at "/db/apps/ahiqar/modules/AnnotationAPI/sedra.xqm";
import module namespace vars="http://ahiqar.uni-goettingen.de/ns/annotations/variants" at "/db/apps/ahiqar/modules/AnnotationAPI/variants.xqm";

declare namespace tei="http://www.tei-c.org/ns/1.0";
declare namespace ore="http://www.openarchives.org/ore/terms/";
declare namespace rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";

declare function san:prepare-unit-tests($fragments as element())
as item()+ {
    let $sysout := util:log-system-out("Creating and storing the AnnotationCollections and AnnotationPages…")
    let $main-collection := map:keys($anno:uris)
    let $languages := map:get($anno:uris, $main-collection) => map:keys()
    for $lang in $languages return
        let $manifests := map:get($anno:uris, $main-collection) => map:get($lang) => map:keys()
        for $manifest in $manifests return
            let $teixml := anno:find-in-map($anno:uris, $manifest)

            let $pages-in-manifest :=
                for $tei in anno:find-in-map($anno:uris, $manifest) return
                    let $doc := commons:open-tei-xml($tei)
                    return
                        $doc//tei:pb[@facs]/@n/string()
            return
                for $page in $pages-in-manifest return
                    let $items :=
                        try {
                            local:get-annotations($teixml, $fragments, $page, false())
                        } catch * {
                            ""
                        }
                    let $result := map { "items": array{$items} } => serialize(map{"method": "json"})
                    let $resource-name := $manifest || "-" || commons:format-page-number($page) || "-items.json"
                    return
                        xmldb:store-as-binary($commons:json, $resource-name, $result)
};

declare function local:get-annotations($teixml-uri as xs:string,
    $fragments as element(),
    $page as xs:string,
    $variants as xs:boolean)
as item()* {
    let $pages := $fragments/page[@n = $page]
    let $log := util:log-system-out("--- Create annotations for page " || $page)
    return
        (
            commons:debug("pre :::::::::"),
            edit:get-annotations($pages, $teixml-uri),
            commons:debug("edit done :::"),
            motifs:get-motifs($pages, $teixml-uri),
            commons:debug("motifs done :"),
            if ($variants) then
                (: variants are only created for Syriac and Arabic texts :)
                for $p in $pages
                where $p//tei:text[not(@type eq "translation")]/@xml:lang = ("ara", "syc")
                return
                    (vars:get-variants($p/tei:TEI, $teixml-uri, $page),
                    commons:debug("variants done:"))
            else
                (),
            (: sedra annotations are only created for Syriac texts :)
            for $p in $pages
                where $p//tei:text[not(@type eq "translation")]/@xml:lang = ("syc")
                return
                    sedra:main($p/tei:TEI, $teixml-uri, $page),
            commons:debug("sedra done ::"),
            (:

            disable line segmentation as long as data is wasted
            :)
            try {
                for $p in $pages[@facs][@type eq "transcription"]
                return ls:get-annotations($teixml-uri, $page, $pages)
            } catch * {
                util:log-system-out( string-join(($err:code , $err:description, $err:value, $err:module), " || "))
            },
            commons:debug("lineseg done ")
        )
};

declare function san:make-items-for-TEI($teixml-uri as xs:string,
    $fragments as element()) {
    let $manifest-uri := local:determine-manifest($teixml-uri)
    let $log := util:log-system-out("Recreate annotation items for TEI file " || $teixml-uri || " (manifest " || $manifest-uri || ")")
    let $pages :=
        for $type in distinct-values($fragments/page/@type/string()) return
            $fragments/page[@type = $type]/@n
    return
        (: $pages holds all available pages. in case of karshuni manuscript, we have each page twice: one for Arabic, one for Karshuni.
        when we retrieve the fragments later in local:get-annotations, this also happens twice (and all annotations are created twice) if
        we don't use distinct-values here :)
        (for $page in distinct-values($pages) return
            let $items :=
                try {
                    (: 3r7p9 is Vat. Arab 74 which is alone in its line of transmission. therefore it doesn't need variants :)
                    (: the following manuscripts are not sorted into a line of transmission yet (therefore no variants)
                        - Lebanon, Ṣarbā (Jūniyah), Ordre Basilien Alepin, MS 956 / textgrid:40z89.0
                        - Lebanon, Beirut, Université Saint-Joseph. Bibliothèque, MS 619 / textgrid:40z8c.0
                        - Université Saint-Joseph. Bibliothèque orientale, MS 621 / textgrid:410br.0
                        - Université Saint-Joseph. Bibliothèque orientale, MS 626 / textgrid:410cr.0
                        - Tellkepe, QACCT 135 / textgrid:417rk.0
                        - Mingana Syriac 237 / textgrid:3r7tt.0
                        - MSS 882 / textgrid:415sp.0
                        - Syr 17 / textgrid:415tw.0
                    :)
                    if ($manifest-uri = ('3r7p9', '40z89', '40z8c', '410br',
                            '410cr', '417rk', '3r7tt', '415sp', '415tw')) then
                        local:get-annotations($teixml-uri, $fragments, $page, false())
                    else
                        local:get-annotations($teixml-uri, $fragments, $page, true())
                } catch * {
                    util:log-system-out("Annotations couldn't be created for " || $teixml-uri || ": " || $page),
                    util:log-system-out("Caught error " || $err:code || ": " || $err:description || " in " || $err:module || " at line " || $err:line-number),
                    util:log-system-out($err:value)
                }
            let $result := map { "items": array{$items} } => serialize(map{"method": "json"})
            let $resource-name := $manifest-uri || "-" || commons:format-page-number($page) || "-items.json"
            return
                xmldb:store-as-binary($commons:json, $resource-name, $result),
        util:log-system-out("Storing finished. For possible errors in this process see exist.log."))
};

declare function local:determine-manifest($teixml-uri as xs:string) {
    for $doc in collection($commons:agg) return
        if (contains($doc//ore:aggregates/@rdf:resource, $teixml-uri)) then
            commons:extract-uri-from-base-uri(base-uri($doc))
        else
            ()
};
