<?xml version="1.0" encoding="UTF-8"?>
<!--
This builder is released under a BSD-3 license as part of the CIMantic Graphs library developed by PNNL.

This software was created under a project sponsored by the U.S. Department of Energy's Office of Electricity, 
an agency of the United States Government. Neither the United States Government nor the United States Department 
of Energy, nor Battelle, nor any of their employees, nor any jurisdiction or organization that has cooperated 
in the development of these materials, makes any warranty, express or implied, or assumes any legal liability 
or responsibility for the accuracy, completeness, or usefulness or any information, apparatus, product, software, 
or process disclosed, or represents that its use would not infringe privately owned rights.

Reference herein to any specific commercial product, process, or service by trade name, trademark, manufacturer, 
or otherwise does not necessarily constitute or imply its endorsement, recommendation, or favoring by the United 
States Government or any agency thereof, or Battelle Memorial Institute. The views and opinions of authors expressed 
herein do not necessarily state or reflect those of the United States Government or any agency thereof.

PACIFIC NORTHWEST NATIONAL LABORATORY operated by BATTELLE for the UNITED STATES DEPARTMENT OF ENERGY 
under Contract DE-AC05-76RL01830
-->
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:a="http://langdale.com.au/2005/Message#"
    xmlns:sawsdl="http://www.w3.org/ns/sawsdl"
    xmlns="http://langdale.com.au/2009/Indent">

    <xsl:output indent="yes" method="xml" encoding="utf-8" />
    <xsl:param name="version"/>
    <xsl:param name="baseURI"/>
    <xsl:param name="ontologyURI"/>
    <xsl:param name="envelope">Profile</xsl:param>
    <xsl:param name="package">au.com.langdale.cimtool.generated</xsl:param>

    <!-- Template for __init__.py file -->
    <xsl:template match="a:Catalog">
        <document>
            <!-- Header text with library imports -->
            <list begin="'''" indent="    " end="'''">
                <item>Annotated CIMantic Graphs data profile init file for
                    <xsl:value-of select="$envelope" />
                </item>
                <item>Generated by CIMTool http://cimtool.org</item>
            </list>
            <!-- Import objects using profile name -->
            <item> from cimgraph.data_profile.<xsl:value-of select="$envelope" />.<xsl:value-of select="$envelope" /> import ( </item>
            <list begin="" indent="    " end="">
                <item>Identity,</item>
            </list>
            <!-- List all CIM classes to be imported, in alphabetical order -->
            <xsl:for-each select="a:Root|a:ComplexType|a:EnumeratedType|a:CompoundType|a:SimpleType">
                <xsl:sort select="name" data-type="text" order="ascending"/>
                
                <xsl:variable name="name">
                    <xsl:call-template name="name">
                        <xsl:with-param name="name" select="@name"/>
                        <xsl:with-param name="type" select="@name"/>
                    </xsl:call-template>
                </xsl:variable>
                
                <list begin="" indent="    " end="">
                    <xsl:value-of select="$name" />
                    <xsl:if test="position()!=last()">, </xsl:if>
                </list>
            </xsl:for-each>
            <item>)</item>
            
            <!-- List all CIM classes to be imported, in alphabetical order -->
            <item> __all__ = [ </item>
            <list begin="" indent="    " end="">
                <item>'Identity',</item>
            </list>
            <xsl:for-each select="a:Root|a:ComplexType|a:EnumeratedType|a:CompoundType|a:SimpleType">
                <xsl:sort select="name" data-type="text" order="ascending"/>
                
                <xsl:variable name="name">
                    <xsl:call-template name="name">
                        <xsl:with-param name="name" select="@name"/>
                        <xsl:with-param name="type" select="@name"/>
                    </xsl:call-template>
                </xsl:variable>
                
                <list begin="" indent="    " end="">
                    '<xsl:value-of select="$name" />'
                    <xsl:if test="position()!=last()">, </xsl:if>
                </list>
            </xsl:for-each>
            <item>]</item>
        </document>
    </xsl:template>
    
    <!-- Template for error handling of missing or reserved names -->
    <xsl:template name="name">
        <xsl:param name="name" select="@name"/>
        <xsl:param name="type" select="@type"/>
        
        <xsl:variable name="cleanName">
            <xsl:call-template name="removeSpecialChars">
                <xsl:with-param name="text" select="$name"/>
            </xsl:call-template>
        </xsl:variable>
        
        <xsl:choose>
            <xsl:when test="contains($name,'EAID_')"><xsl:value-of select="$type"/></xsl:when>
            <xsl:when test="string-length($cleanName) > 0 and translate(substring($cleanName,1,1),'0123456789','') = ''">_<xsl:value-of select="$cleanName"/></xsl:when>
            <xsl:when test="$cleanName = 'and'">_and</xsl:when>
            <xsl:when test="$cleanName = 'as'">_as</xsl:when>
            <xsl:when test="$cleanName = 'assert'">_assert</xsl:when>
            <xsl:when test="$cleanName = 'break'">_break</xsl:when>
            <xsl:when test="$cleanName = 'class'">_class</xsl:when>
            <xsl:when test="$cleanName = 'continue'">_continue</xsl:when>
            <xsl:when test="$cleanName = 'def'">_def</xsl:when>
            <xsl:when test="$cleanName = 'del'">_del</xsl:when>
            <xsl:when test="$cleanName = 'elif'">_elif</xsl:when>
            <xsl:when test="$cleanName = 'else'">_else</xsl:when>
            <xsl:when test="$cleanName = 'except'">_except</xsl:when>
            <xsl:when test="$cleanName = 'finally'">_finally</xsl:when>
            <xsl:when test="$cleanName = 'for'">_for</xsl:when>
            <xsl:when test="$cleanName = 'from'">_from</xsl:when>
            <xsl:when test="$cleanName = 'global'">_global</xsl:when>
            <xsl:when test="$cleanName = 'if'">_if</xsl:when>
            <xsl:when test="$cleanName = 'import'">_import</xsl:when>
            <xsl:when test="$cleanName = 'in'">_in</xsl:when>
            <xsl:when test="$cleanName = 'is'">_is</xsl:when>
            <xsl:when test="$cleanName = 'lambda'">_lambda</xsl:when>
            <xsl:when test="$cleanName = 'nonlocal'">_nonlocal</xsl:when>
            <xsl:when test="$cleanName = 'not'">_not</xsl:when>
            <xsl:when test="$cleanName = 'or'">_or</xsl:when>
            <xsl:when test="$cleanName = 'pass'">_pass</xsl:when>
            <xsl:when test="$cleanName = 'raise'">_raise</xsl:when>
            <xsl:when test="$cleanName = 'return'">_return</xsl:when>
            <xsl:when test="$cleanName = 'try'">_try</xsl:when>
            <xsl:when test="$cleanName = 'while'">_while</xsl:when>
            <xsl:when test="$cleanName = 'with'">_with</xsl:when>
            <xsl:when test="$cleanName = 'yield'">_yield</xsl:when>
            <xsl:otherwise><xsl:value-of select="$cleanName"/></xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
    <xsl:template name="removeSpecialChars">
        <xsl:param name="text"/>
        <xsl:param name="pos" select="1"/>
        <xsl:param name="result" select="''"/>
        
        <xsl:choose>
            <xsl:when test="$pos > string-length($text)">
                <xsl:value-of select="$result"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:variable name="char" select="substring($text, $pos, 1)"/>
                <xsl:variable name="validChars" select="'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'"/>
                <xsl:variable name="isValidChar" select="contains($validChars, $char)"/>
                
                <xsl:call-template name="removeSpecialChars">
                    <xsl:with-param name="text" select="$text"/>
                    <xsl:with-param name="pos" select="$pos + 1"/>
                    <xsl:with-param name="result">
                        <xsl:choose>
                            <xsl:when test="$isValidChar">
                                <xsl:value-of select="concat($result, $char)"/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:value-of select="$result"/>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:with-param>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
    
</xsl:stylesheet>
