<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns="http://xml.insee.intra/schema/annuaire/"
    xmlns:a="http://xml.insee.intra/schema/annuaire/" xmlns:q="http://xml.insee.intra/schema/qbe/"
    xmlns:l="http://xml.insee.intra/schema/ldap/" xmlns:exsl="http://exslt.org/common"
    extension-element-prefixes="exsl" version="1.0">
    <xsl:import href="scope.xsl"/>
    <xsl:strip-space elements="*"/>
    <xsl:output media-type="xml" omit-xml-declaration="yes"/>
    <xsl:key name="resources" match="*[@rdf:ID]" use="concat('#', @rdf:ID)"/>
    <xsl:key name="backResources" match="*[@rdf:resource]"
        use="substring-after( @rdf:resource, '#' )"/>
    <xsl:template match="/rdf:RDF">
        <!--<xsl:text>xquery version "1.0";&#xa;</xsl:text>-->
        <rdf:RDF>
            <xsl:variable name="simple">
                <xsl:apply-templates select="." mode="scope"/>
            </xsl:variable>
            <xsl:apply-templates select="exsl:node-set($simple)/rdf:RDF/q:select" mode="what"/>
        </rdf:RDF>
    </xsl:template>
    <xsl:template match="q:select" mode="what">
        <xsl:text>&#xa;{ for $x in /rdf:RDF/a:</xsl:text>
        <xsl:variable name="what" select="key( 'resources', q:what/@rdf:resource)"/>
        <xsl:value-of select="local-name($what)"/>
        <xsl:text> </xsl:text>
        <xsl:apply-templates select="/rdf:RDF/q:select/q:where" mode="where">
            <xsl:with-param name="what" select="$what"/>
        </xsl:apply-templates>
        <xsl:text>&#xa;return </xsl:text>
        <xsl:apply-templates select="$what" mode="return">
            <xsl:with-param name="what" select="$what"/>
        </xsl:apply-templates>
        <xsl:text> }&#xa;</xsl:text>
    </xsl:template>
    <xsl:template match="a:*" mode="return">
        <xsl:text>$x</xsl:text>
    </xsl:template>
    <xsl:template match="a:*[*]" mode="return">
        <xsl:element name="{local-name(.)}">
            <xsl:attribute name="rdf:about">
                <xsl:text>{$x/@rdf:about}</xsl:text>
            </xsl:attribute>
            <xsl:text>{</xsl:text>
            <xsl:apply-templates mode="return-list"/>
            <xsl:text>}</xsl:text>
        </xsl:element>
    </xsl:template>
    <xsl:template match="a:*" mode="return-list">
        <xsl:if test="position() > 1">, </xsl:if>
        <xsl:text>$x/a:</xsl:text>
        <xsl:value-of select="local-name(.)"/>
    </xsl:template>
    <!-- 
    
    Mode "where"
    
    -->
    <xsl:template match="q:where" mode="where">
        <xsl:param name="what"/>
        <xsl:text>&#xa;where </xsl:text>
        <xsl:for-each select="key('resources', @rdf:resource)">
            <xsl:text>$x[</xsl:text>
            <xsl:apply-templates mode="where"/>
            <xsl:text>]</xsl:text>
        </xsl:for-each>
    </xsl:template>
    <xsl:template match="rdf:Description" mode="where">
        <xsl:text>/@rdf:resource = /rdf:RDF/*</xsl:text>
        <xsl:if test="*">[</xsl:if>
        <xsl:apply-templates select="*" mode="where"/>
        <xsl:if test="*">]</xsl:if>
        <xsl:text>/@rdf:about</xsl:text>
    </xsl:template>
    <xsl:template match="a:*|l:*" mode="where">
        <xsl:text>**** (unknown element) </xsl:text>
        <xsl:value-of select="name()"/>
        <xsl:text>***</xsl:text>
    </xsl:template>
    <xsl:template match="a:*[@rdf:resource]|l:*[@rdf:resource]" mode="where">
        <xsl:apply-templates select="." mode="operator"/>
        <xsl:apply-templates select="." mode="prefix"/>
        <xsl:value-of select="local-name()"/>
        <xsl:apply-templates select="key('resources', @rdf:resource)" mode="where"/>
        <xsl:text/>
    </xsl:template>
 <!--   <xsl:template match="a:*[text()]|l:*[text()]" priority=".6" mode="where">
        <xsl:apply-templates select="." mode="operator"/>
        <xsl:apply-templates select="." mode="prefix"/>
        <xsl:value-of select="local-name()"/>
        <xsl:apply-templates select="text()" mode="where"/>
        <xsl:text/>
    </xsl:template>-->
    <xsl:template match="q:*" mode="where">
        <!-- 
        
        Default
        
        -->
        <xsl:text> *** </xsl:text>
        <xsl:value-of select="name()"/>
        <xsl:text> *** </xsl:text>
    </xsl:template>
    <xsl:template match="q:conditions" mode="where">
        <xsl:text>[ </xsl:text>
        <xsl:apply-templates mode="where"/>
        <xsl:text> ]</xsl:text>
    </xsl:template>
    <xsl:template match="q:if" mode="where">
        <xsl:variable name="children" select="key('resources', @rdf:resource)"/>
        <xsl:variable name="needParenthesis"
            select="(parent::q:any or parent::q:all) and count($children/*) > 1"/>
        <xsl:if test="$needParenthesis">( </xsl:if>
        <xsl:apply-templates select="$children" mode="where"/>
        <xsl:if test="$needParenthesis"> )</xsl:if>
    </xsl:template>
    <xsl:template match="q:if-not" mode="where">
        <xsl:text>not ( </xsl:text>
        <xsl:apply-templates select="key('resources', @rdf:resource)" mode="where"/>
        <xsl:text> )</xsl:text>
    </xsl:template>
    <xsl:template match="q:any" mode="where">
        <xsl:apply-templates mode="where"/>
    </xsl:template>
    <xsl:template match="q:all" mode="where">
        <xsl:apply-templates mode="where"/>
    </xsl:template>
    <xsl:template match="q:equals" mode="where">
        <xsl:apply-templates select="." mode="operator"/>
        <xsl:text>. = '</xsl:text>
        <xsl:value-of select="."/>
        <xsl:text>' </xsl:text>
    </xsl:template>
    <xsl:template match="q:starts-with" mode="where">
        <xsl:apply-templates select="." mode="operator"/>
        <xsl:text>starts-with(., '</xsl:text>
        <xsl:value-of select="."/>
        <xsl:text>')</xsl:text>
    </xsl:template>
    <xsl:template match="q:contains" mode="where">
        <xsl:apply-templates select="." mode="operator"/>
        <xsl:text>contains(., '</xsl:text>
        <xsl:value-of select="."/>
        <xsl:text>')</xsl:text>
    </xsl:template>
    <xsl:template match="q:ends-with" mode="where">
        <xsl:apply-templates select="." mode="operator"/>
        <xsl:text>contains(., '</xsl:text>
        <xsl:value-of select="."/>
        <xsl:text>') and substring-after(., '</xsl:text>
        <xsl:value-of select="."/>
        <xsl:text>') = ''</xsl:text>
    </xsl:template>
    <xsl:template match="q:simple-match" mode="where">
        <xsl:apply-templates select="." mode="operator"/>
        <xsl:text>matches(., '^</xsl:text>
        <xsl:call-template name="simple-match"/>
        <xsl:text>$')</xsl:text>
    </xsl:template>
    <xsl:template match="q:exists" mode="where"/>
    <xsl:template match="q:is-empty" mode="where">
        <xsl:apply-templates select="." mode="operator"/>
        <xsl:text>. = ''</xsl:text>
    </xsl:template>
    <!-- 
    
    Mode "operator"
    
    -->
    <xsl:template match="*" mode="operator"/>
    <xsl:template match="*[count(../*) > 1]" mode="operator" priority=".10">
        <xsl:if test="preceding-sibling::*"> and </xsl:if>
    </xsl:template>
    <xsl:template match="q:all/*" mode="operator">
        <xsl:if test="preceding-sibling::*"> and </xsl:if>
    </xsl:template>
    <xsl:template match="q:any/*" mode="operator">
        <xsl:if test="preceding-sibling::*"> or </xsl:if>
    </xsl:template>
    <!-- 
    
    Mode "prefix"
    
    -->
    <xsl:template match="a:*" mode="prefix">
        <xsl:text>a:</xsl:text>
    </xsl:template>
    <xsl:template match="l:*" mode="prefix">
        <xsl:text>l:</xsl:text>
    </xsl:template>
    <!--<xsl:template match="*" mode="prefix" priority="0">
        <xsl:text>*** unknown prefix ***</xsl:text>
    </xsl:template>-->
    
    <!-- 
    
    Simple match
    
    -->
    <xsl:template name="simple-match">
        <xsl:param name="txt" select="."/>
        <xsl:choose>
            <xsl:when test="contains($txt, '*')">
                <xsl:value-of select="substring-before($txt, '*')"/>
                <xsl:text>.*</xsl:text>
                <xsl:call-template name="simple-match">
                    <xsl:with-param name="txt" select="substring-after($txt, '*')"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$txt"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>
