<?xml version="1.0" encoding="utf-8"?>
<sch:pattern id="ISM-ID-00171" xmlns:sch="http://purl.oclc.org/dsdl/schematron">
    <sch:p id="ruleText">
        [ISM-ID-00171][Warning] If ISM-CAPCO-RESOURCE and displayOnlyTo is specified on 
        the resource element then all classified portions must be displayOnlyTo 
        the same country
        
        Human Readable: USA documents having DISPLAYONLY Data at the resource level
        must have all classified portions authorized for DISPLAYONLY the same 
        country
    </sch:p>
    <sch:p id="codeDesc">
        If CAPCO rules do not apply to the document then the rule does not apply
        and we return true. 
        
        Otherwise, we count the number of classified portions by looping through 
        $partTags. Then we get a list of all country codes listed in both 
        displayOnlyTo and releasableTo attributes on those classified portions and 
        tokenize them down so each node of the list is a single token. If any of 
        these tokens contains one of the EYES countries designations (TEYE, ACGU, 
        or FVEY) the countries that are included in the designations are inserted. 
        Then common countries are found for the releasableTo and displayOnlyTo 
        tokens by finding the tokens whose count equals the number of classified 
        portions. Since displayOnlyTo tokens include releasableTo tokens, the common
        releasableTo countries are removed from the final displayOnlyTo common 
        countries. The displayOnlyTo values in the banner are then compared to the 
        final displayOnlyTo common countries that were determined based on the 
        portion values. 
        
        If the attribute disseminationControls appears on the banner with a value 
        containing [DISPLAYONLY] then the rule will return true if the banner values 
        match the common countries between portions. If the attribute 
        disseminationControls does not appear on the banner or does not contain the 
        value [DISPLAYONLY], then the rule will return true if there are no common 
        countries between portions.

    </sch:p> 
    <sch:rule context="//*[generate-id(.) = generate-id($ISM_RESOURCE_ELEMENT) 
		and @ism:displayOnlyTo]">
        <sch:let name="numClassParts" value="
            count(
                for $each in $partTags return
                    if(matches($each/@ism:classification,'^(TS|S|C)$'))
                        then 1
                        else null
            )
            "/>
        <sch:let name="relToCodes" value="
            for $each in $partTags return
                if(matches($each/@ism:classification,'^(TS|S|C)$'))
                    then distinct-values(tokenize($each/@ism:releasableTo,' '))
                else null
            "/>
        <sch:let name="relToCode_tok" value="for $each in $relToCodes return tokenize($each,' ')"/>
        
        <sch:let name="dispToCodes" value="
            for $each in $partTags return
                if(matches($each/@ism:classification,'^(TS|S|C)$'))
                    then distinct-values(tokenize($each/@ism:displayOnlyTo,' '))
                else null
            "/>
        <sch:let name="dispToCode_tok" value="for $each in $dispToCodes return tokenize($each,' ')"/>
        
        <!-- Expand THREE-, FOUR- and FIVE-EYES countries in the banner and portions, ignoring 'USA' -->
        <sch:let name="expandBannerEYES_tok" value="
            distinct-values(
                for $tok in (
                    for $each in $bannerDisplayOnlyTo_tok return
                        if ($each = 'TEYE') then $TEYE_tok
                        else if ($each = 'ACGU') then $ACGU_tok
                        else if ($each = 'FVEY') then $FVEY_tok
                        else $each
                    ) return
                    if ($tok != 'USA') then $tok else null     
            )
            "/>
        <sch:let name="expandPortionDispTo_tok" value="
            for $tok in (
                for $each in $dispToCode_tok return
                    if ($each = 'TEYE') then $TEYE_tok
                    else if ($each = 'ACGU') then $ACGU_tok
                    else if ($each = 'FVEY') then $FVEY_tok
                    else $each
                ) return
                if ($tok != 'USA') then $tok else null
            "/>
        <sch:let name="expandPortionRelTo_tok" value="
            for $tok in (
                for $each in $relToCode_tok return
                    if ($each = 'TEYE') then $TEYE_tok
                    else if ($each = 'ACGU') then $ACGU_tok
                    else if ($each = 'FVEY') then $FVEY_tok
                    else $each
                ) return
                if ($tok != 'USA') then $tok else null 
            "/>
        
        <sch:let name="expandPortionDispAndRel_tok" value="
            for $each in string-join(($expandPortionDispTo_tok, $expandPortionRelTo_tok), ' ') 
                return tokenize($each,' ')
            "/>
        
        <!-- Find countries common to displayOnlyTo and releasableTo portions -->
        <sch:let name="commonDispTo" value="
            for $each in distinct-values($expandPortionDispAndRel_tok) return
                if (
                    count(
                        for $tok in $expandPortionDispAndRel_tok return
                            if($each=$tok) then $tok else null
                    ) >= $numClassParts
                ) then $each
                else null                    
            "/>
        <sch:let name="commonRelTo" value="
            for $each in distinct-values($expandPortionRelTo_tok) return
                if (
                    count(
                        for $tok in $expandPortionRelTo_tok return
                            if($each=$tok) then $tok else null
                    ) >= $numClassParts
            ) then $each
            else null                    
            "/>
        
        <!-- Remove releasableTo common countries from displayOnlyTo -->
        <sch:let name="finalDispTo" value="
            if (count($commonRelTo) > 0) then
                for $tok in $commonRelTo return
                    for $each in $commonDispTo return
                        if ($each = $tok) then null else $each
            else $commonDispTo
                    
            "/>
        <sch:let name="commonMatchesBanner" value="
            count($expandBannerEYES_tok) > 0 and
            count($finalDispTo) > 0 and 
            ( 
                every $tok in $expandBannerEYES_tok satisfies
                    index-of($finalDispTo, $tok) > 0
            ) and (
                every $tok in $finalDispTo satisfies
                    index-of($expandBannerEYES_tok, $tok) > 0
            )
            "/>
        
        <sch:assert 
            id="ISM-00171" 
            test="
            if(not($ISM_CAPCO_RESOURCE)) then true() 
            else if (index-of($bannerDisseminationControls_tok, 'DISPLAYONLY') > 0) then $commonMatchesBanner
            else not(count($finalDispTo) > 0)
            " 
            flag="warning">
            [ISM-ID-00171][Warning]USA documents having DISPLAYONLY Data at the resource level
            must have all classified portions authorized for DISPLAYONLY the same 
            country
        </sch:assert>
    </sch:rule>
</sch:pattern>