<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
	xmlns:local="urn:local"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    xmlns:tei="http://www.tei-c.org/ns/1.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xi xs">

    <xsl:param name="debug-xinclude" as="xs:boolean" select="true()"/>

    <!-- ============================================================ -->
    <!-- FUNCTIONS                                                    -->
    <!-- ============================================================ -->

	<xsl:function name="local:make-xpath" as="xs:string">
	    <xsl:param name="node" as="node()"/>
	
	    <xsl:variable name="parts" as="xs:string*"
	        select="
	            for $i in $node/ancestor-or-self::*
	            return
	                concat(
	                    local-name($i),
	                    if (not(exists($i/parent::*/*[name() = name($i)][2])))
	                    then ''
	                    else concat(
	                        '[',
	                        count($i/preceding-sibling::*[name() = name($i)]) + 1,
	                        ']'
	                    )
	                )
	        "
	    />
	
	    <xsl:sequence select="concat('/', string-join($parts, '/'))"/>
	</xsl:function>


    <!-- ============================================================ -->
    <!-- ENTRY POINT                                                  -->
    <!-- ============================================================ -->

    <xsl:template match="/" mode="#default">
        <!-- NOTE: no "as" attribute here – this forces classic RTF
             (temporary tree) construction, guaranteeing a single
             document node regardless of how many top-level items
             the sequence constructor produces internally. -->
        <xsl:variable name="expanded">
            <xsl:apply-templates select="." mode="xinclude"/>
        </xsl:variable>

        <xsl:if test="$debug-xinclude">
            <xsl:message>=== XInclude expansion complete ===</xsl:message>
        </xsl:if>

		<xsl:apply-templates select="$expanded" mode="processing"/>
        
        <!--   
        for debugging you can output the expanded but not transformed version with this:
        
        <xsl:copy-of select="$expanded" />
        
         -->
        

    </xsl:template>

    <!-- ============================================================ -->
    <!-- MODE "xinclude": IDENTITY TEMPLATE                            -->
    <!-- ============================================================ -->

    <xsl:template match="node() | @*" mode="xinclude">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*" mode="xinclude"/>
        </xsl:copy>
    </xsl:template>

    <!-- ============================================================ -->
    <!-- PERMISSIVE MATCH: xi:include in correct namespace, OR         -->
    <!-- bare/unqualified <include href="textgrid:..">                 -->
    <!-- ============================================================ -->

    <xsl:template match="xi:include[starts-with(@href, 'textgrid:')]"
                  mode="xinclude">

        <xsl:if test="$debug-xinclude">
            <xsl:message>
                Found include candidate: name=<xsl:value-of select="name(.)"/>
                href=<xsl:value-of select="@href"/>
                in-namespace=<xsl:value-of select="namespace-uri(.) = 'http://www.w3.org/2001/XInclude'"/>
            </xsl:message>
        </xsl:if>

        <xsl:variable name="parse" select="(@parse, 'xml')[1]" as="xs:string"/>
        <xsl:variable name="raw-href" select="@href" as="xs:string?"/>

        <xsl:choose>
            <xsl:when test="not($raw-href)">
                <xsl:message terminate="yes">
                    include element without @href is not supported.
                </xsl:message>
            </xsl:when>
            <xsl:otherwise>
                <xsl:variable name="href"
                    select="resolve-uri($raw-href, base-uri(.))"
                    as="xs:anyURI"/>

                <xsl:if test="$debug-xinclude">
                    <xsl:message>
                        Resolved href=<xsl:value-of select="$href"/>
                        (base-uri was <xsl:value-of select="base-uri(.)"/>)
                    </xsl:message>
                </xsl:if>

                <xsl:choose>
                    <xsl:when test="$parse = 'text'">
                        <xsl:call-template name="xi-include-text">
                            <xsl:with-param name="href" select="$href"/>
                        </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:call-template name="xi-include-xml">
                            <xsl:with-param name="href" select="$href"/>
                        </xsl:call-template>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template name="xi-include-xml">
        <xsl:param name="href" as="xs:string"/>
        <xsl:choose>
            <xsl:when test="doc-available($href)">
                <xsl:variable name="doc" select="doc($href)/*" as="element()"/>

                <xsl:if test="$debug-xinclude">
                    <xsl:message>
                        Successfully fetched <xsl:value-of select="$href"/>,
                        nested includes found = <xsl:value-of select="
                            count($doc//xi:include) +
                            count($doc//*[local-name()='include'][starts-with(@href,'textgrid:')])"/>
                    </xsl:message>
                    <xsl:if test="string(name($doc)) eq 'xsl:stylesheet '">
                    <xsl:message terminate="yes">
                    	ERROR: included element is xsl:stylesheet.
                	</xsl:message>
                    </xsl:if>
                </xsl:if>

                <xsl:apply-templates select="$doc/node()" mode="xinclude"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:if test="$debug-xinclude">
                    <xsl:message>
                        ERROR: doc-available() returned false for href=<xsl:value-of select="$href"/>
                    </xsl:message>
                </xsl:if>
                <xsl:call-template name="xi-fallback">
                    <xsl:with-param name="href" select="$href"/>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>


    </xsl:template>

    <xsl:template name="xi-include-text">
        <xsl:param name="href" as="xs:string"/>
        <xsl:variable name="encoding" select="(@encoding, 'UTF-8')[1]" as="xs:string"/>

        <xsl:choose>
            <xsl:when test="unparsed-text-available($href, $encoding)">
                <xsl:value-of select="unparsed-text($href, $encoding)"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:call-template name="xi-fallback">
                    <xsl:with-param name="href" select="$href"/>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template name="xi-fallback">
        <xsl:param name="href" as="xs:string"/>

        <xsl:choose>
            <xsl:when test="xi:fallback | *[local-name()='fallback']">
                <xsl:apply-templates select="(xi:fallback | *[local-name()='fallback'])/node()" mode="xinclude"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:message terminate="no">
                    XInclude resolution failed for href="<xsl:value-of select="$href"/>"
                    and no fallback was provided.
                </xsl:message>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
    <!-- ============================================================ -->
    <!-- MODE "processing": IDENTITY TEMPLATE                         -->
    <!-- ============================================================ --> 
  <!-- Copy everything else unchanged -->
  <xsl:template match="@*|text()|comment()|processing-instruction()" mode="processing">
    <xsl:copy/>
  </xsl:template>

    
    <!-- ============           Ignored Nodes            ============ -->
    <xsl:template match="processing-instruction()"  mode="processing" />

    <!-- ============================================================ -->
    <!-- PROCESSING LOGIC GOES HERE                                   -->
    <!-- ============================================================ -->
        <!-- Rename every element -->
  <xsl:template match="*" mode="processing">
    <xsl:element name="{concat('tei-', local-name())}">
    	<xsl:attribute name="xml:id" select="generate-id()" />
    	<xsl:attribute name="sameAs" select="local:make-xpath(.)" />
      	<xsl:apply-templates select="@*|node()" mode="processing"/>
    </xsl:element>
  </xsl:template>
	

</xsl:stylesheet>