<xsl:transform version="1.0"
               xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
               xmlns:axe="http://www.microsoft.com/axe/assessment/manifest">
    
    <xsl:output method="xml" indent="yes" encoding="utf-8"/>
    <xsl:variable name="manifest" select="document('EcoSysInfo.asmtx')/axe:AxeAssessmentManifest"/>
    
    <xsl:template match="/EcoSysInfo">
        <AssessmentResult>
            <Iterations>
                <Iteration>
                    
                    <MetricValues>
                        
                        <xsl:for-each select="*[count(*)=0]">
                            <xsl:call-template name="MetricValue"/>
                        </xsl:for-each>
                        <xsl:for-each select="*/*[count(*)=0]">
                            <xsl:call-template name="MetricValue"/>
                        </xsl:for-each>
                        <xsl:for-each select="System/*/*[count(*)=0]">
                            <xsl:call-template name="MetricValue"/>
                        </xsl:for-each>

                        <MetricValue>
                            <ProgrammaticName>OSVersion</ProgrammaticName>
                            <Value><xsl:value-of select="OSVersion/Major"/>.<xsl:value-of select="OSVersion/Minor"/>.<xsl:value-of select="OSVersion/Build"/></Value>
                        </MetricValue>

                        <MetricValue>
                            <ProgrammaticName>WinEIScore</ProgrammaticName>
                            <Value>
                                <xsl:for-each select="WinEIScores/*">
                                    <xsl:sort select="."/>
                                    <xsl:if test="position()=1">
                                        <xsl:value-of select="."/>
                                    </xsl:if>
                                </xsl:for-each>
                            </Value>
                        </MetricValue>

                        <MetricValue>
                            <ProgrammaticName>Memory_TotalPhysical</ProgrammaticName>
                            <Value><xsl:value-of select="Memory/TotalPhysical/Bytes div 1048576"/></Value>
                        </MetricValue>
                        <MetricValue>
                            <ProgrammaticName>Memory_AvailablePhysical</ProgrammaticName>
                            <Value><xsl:value-of select="Memory/AvailablePhysical/Bytes div 1048576"/></Value>
                        </MetricValue>

                        <MetricValue>
                            <ProgrammaticName>SystemDiskId</ProgrammaticName>
                            <Value><xsl:value-of select="Disk/SystemDisk/@id"/></Value>
                        </MetricValue>
                        <MetricValue>
                            <ProgrammaticName>DiskNum</ProgrammaticName>
                            <Value><xsl:value-of select="Disk/SystemDisk/DiskNum"/></Value>
                        </MetricValue>
                        <MetricValue>
                            <ProgrammaticName>DiskVendor</ProgrammaticName>
                            <Value><xsl:value-of select="Disk/SystemDisk/Vendor"/></Value>
                        </MetricValue>
                        <MetricValue>
                            <ProgrammaticName>DiskModel</ProgrammaticName>
                            <Value><xsl:value-of select="Disk/SystemDisk/Model"/></Value>
                        </MetricValue>
                        <MetricValue>
                            <ProgrammaticName>DiskSize</ProgrammaticName>
                            <Value><xsl:value-of select="Disk/SystemDisk/Size div 1073741824"/></Value>
                        </MetricValue>
                        <xsl:for-each select="Disk/SystemDisk/WriteCacheEnabled[count(*)=0]">
                            <xsl:call-template name="MetricValue"/>
                        </xsl:for-each>

                        <xsl:for-each select="Devices[Device]">
                            <xsl:call-template name="TestCaseCount"/>
                        </xsl:for-each>
                        <xsl:for-each select="Networking/Adapters[Adapter]">
                            <xsl:call-template name="TestCaseCount"/>
                        </xsl:for-each>
                        <xsl:for-each select="Processor[Instance]">
                            <xsl:call-template name="TestCaseCount"/>
                        </xsl:for-each>
                        <xsl:for-each select="Disk[*]">
                            <xsl:call-template name="TestCaseCount"/>
                        </xsl:for-each>
                        <xsl:for-each select="InstalledSoftware[Software]">
                            <xsl:call-template name="TestCaseCount"/>
                        </xsl:for-each>
                        <xsl:for-each select="Processes[Process]">
                            <xsl:call-template name="TestCaseCount"/>
                        </xsl:for-each>
                        <xsl:for-each select="Services[Service]">
                            <xsl:call-template name="TestCaseCount"/>
                        </xsl:for-each>
                        
                    </MetricValues>
                    
                    <TestCases>

                        <xsl:for-each select="Networking/Adapters/Adapter">
                            <xsl:call-template name="TestCase"/>
                        </xsl:for-each>

                        <xsl:for-each select="Processor/Instance">
                            <xsl:call-template name="TestCase">
                                <xsl:with-param name="nesting">2</xsl:with-param>
                            </xsl:call-template>
                        </xsl:for-each>
                        
                        <xsl:for-each select="Devices/Device">
                            <xsl:call-template name="TestCase"/>
                        </xsl:for-each>

                        <xsl:for-each select="Memory/DIMM">
                            <xsl:call-template name="TestCase"/>
                        </xsl:for-each>
                        
                        <xsl:for-each select="Monitors/Monitor">
                        <TestCase>
                            <Key>Monitor_<xsl:value-of select="@id"/></Key>
                            <Name><xsl:value-of select="DeviceName"/></Name>
                            <Parents>
                                <Parent>Monitor</Parent>
                            </Parents>
                            <MetricValues>
                                <MetricValue>
                                    <ProgrammaticName>Monitor_Primary</ProgrammaticName>
                                    <Value>
                                        <xsl:choose>
                                            <xsl:when test="@primary=0">FALSE</xsl:when>
                                            <xsl:otherwise>TRUE</xsl:otherwise>
                                        </xsl:choose>
                                    </Value>
                                </MetricValue>
                                <xsl:for-each select="*">
                                <MetricValue>
                                    <ProgrammaticName>Monitor_<xsl:value-of select="name()"/></ProgrammaticName>
                                    <Value><xsl:value-of select="."/></Value>
                                </MetricValue>
                                </xsl:for-each>
                            </MetricValues>
                        </TestCase>
                        </xsl:for-each>
                        
                        <xsl:for-each select="Disk/Disk">
                        <TestCase>
                            <Key>Disk_<xsl:value-of select="position()"/></Key>
                            <Name>Other Drive #<xsl:value-of select="DiskNum"/></Name>
                            <Parents>
                                <Parent>Disk</Parent>
                            </Parents>
                            <MetricValues>
                                <MetricValue>
                                    <ProgrammaticName>OtherDiskId</ProgrammaticName>
                                    <Value><xsl:value-of select="@id"/></Value>
                                </MetricValue>
                                <MetricValue>
                                    <ProgrammaticName>DiskNum</ProgrammaticName>
                                    <Value><xsl:value-of select="DiskNum"/></Value>
                                </MetricValue>
                                <MetricValue>
                                    <ProgrammaticName>DiskVendor</ProgrammaticName>
                                    <Value><xsl:value-of select="Vendor"/></Value>
                                </MetricValue>
                                <MetricValue>
                                    <ProgrammaticName>DiskModel</ProgrammaticName>
                                    <Value><xsl:value-of select="Model"/></Value>
                                </MetricValue>
                                <MetricValue>
                                    <ProgrammaticName>DiskSize</ProgrammaticName>
                                    <Value><xsl:value-of select="Size div 1073741824"/></Value>
                                </MetricValue>                                
                                <xsl:for-each select="WriteCacheEnabled[count(*)=0]">
                                    <xsl:call-template name="MetricValue"/>
                                </xsl:for-each>
                                
                            </MetricValues>                            
                        </TestCase>
                        </xsl:for-each>

                        <xsl:for-each select="InstalledSoftware/Software">
                            <xsl:call-template name="TestCase"/>
                        </xsl:for-each>

                        <xsl:for-each select="Processes/Process">
                            <xsl:call-template name="TestCase"/>
                        </xsl:for-each>

                        <xsl:for-each select="Services/Service">
                            <xsl:call-template name="TestCase"/>
                        </xsl:for-each>
                        
                    </TestCases>
                    
                </Iteration>
            </Iterations>
        </AssessmentResult>
    </xsl:template>

    <xsl:template name="MetricValue">
        <xsl:variable name="progname"><xsl:if test="not(name(parent::*)=name(/*))"><xsl:value-of select="name(parent::*)"/>_</xsl:if><xsl:value-of select="name()"/></xsl:variable>
        <xsl:variable name="metricdef" select="$manifest/axe:MetricDefinitions/axe:MetricDefinition[axe:Description/axe:ProgrammaticName=$progname]"/>
        <xsl:if test="count($metricdef)&gt;0">
            <xsl:variable name="value">
                <xsl:choose>
                    <xsl:when test="@Friendly"><xsl:value-of select="@Friendly"/></xsl:when>
                    <xsl:when test="@friendly"><xsl:value-of select="@friendly"/></xsl:when>
                    <xsl:when test="@desc"><xsl:value-of select="@desc"/></xsl:when>
                    <xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
            <xsl:variable name="metricvalue">
                <xsl:choose>
                    <xsl:when test="count($metricdef/axe:Type/axe:Boolean)=1">
                        <xsl:choose>
                            <xsl:when test="translate($value, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')='UNKNOWN'"></xsl:when>
                            <xsl:when test="translate($value, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')='TRUE'"><xsl:copy-of select="$value"/></xsl:when>
                            <xsl:when test="translate($value, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')='FALSE'"><xsl:copy-of select="$value"/></xsl:when>
                            <xsl:when test="translate($value, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')='YES'">TRUE</xsl:when>
                            <xsl:when test="translate($value, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')='NO'">FALSE</xsl:when>
                            <xsl:when test="$value=0">FALSE</xsl:when>
                            <xsl:otherwise>TRUE</xsl:otherwise>
                        </xsl:choose>
                    </xsl:when>
                    <xsl:otherwise><xsl:copy-of select="$value"/></xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
            <xsl:if test="$metricvalue != ''">
                <MetricValue>
                    <ProgrammaticName><xsl:copy-of select="$progname"/></ProgrammaticName>
                    <Value><xsl:copy-of select="$metricvalue"/></Value>
                </MetricValue>
            </xsl:if>
        </xsl:if>
    </xsl:template>
    
    <xsl:template name="MetricDefinition">
        <xsl:variable name="progname"><xsl:if test="not(name(parent::*)=name(/*))"><xsl:value-of select="name(parent::*)"/>_</xsl:if><xsl:value-of select="name()"/></xsl:variable>
        <MetricDefinition>
            <Description>
                <ProgrammaticName><xsl:copy-of select="$progname"/></ProgrammaticName>
                <DisplayName><xsl:value-of select="name()"/></DisplayName>
            </Description>
            <Type>
                <String/>
            </Type>
        </MetricDefinition>
    </xsl:template>
    
    <xsl:template name="PresentationColumns">
        <xsl:variable name="progname"><xsl:if test="not(name(parent::*)=name(/*))"><xsl:value-of select="name(parent::*)"/>_</xsl:if><xsl:value-of select="name()"/></xsl:variable>
        <Column>
            <Metric><xsl:copy-of select="$progname"/></Metric>
        </Column>
    </xsl:template>
    
    <xsl:template name="TestCaseCount">
        <xsl:variable name="progname"><xsl:if test="not(name(parent::*)=name(/*))"><xsl:value-of select="name(parent::*)"/>_</xsl:if><xsl:value-of select="name()"/></xsl:variable>
        <xsl:variable name="metricdef" select="$manifest/axe:MetricDefinitions/axe:MetricDefinition[axe:Description/axe:ProgrammaticName=$progname]"/>
        <xsl:if test="count($metricdef)&gt;0">
            <MetricValue>
                <ProgrammaticName><xsl:copy-of select="$progname"/></ProgrammaticName>
                <Value><xsl:value-of select="count(*)"/></Value>
            </MetricValue>
        </xsl:if>
    </xsl:template>

    <xsl:template name="TestCase">
        <xsl:param name="nesting">1</xsl:param>
        <TestCase>
            <Key>
                <xsl:value-of select="name()"/>_<xsl:choose>
                    <xsl:when test="@id"><xsl:value-of select="@id"/></xsl:when>
                    <xsl:otherwise><xsl:value-of select="position()"/></xsl:otherwise>
                </xsl:choose>
            </Key>
            <Name>
                <xsl:choose>
                    <xsl:when test="DeviceName"><xsl:value-of select="DeviceName"/></xsl:when>
                    <xsl:when test="ProcessorName"><xsl:value-of select="ProcessorName"/></xsl:when>
                    <xsl:when test="Name"><xsl:value-of select="Name"/></xsl:when>
                    <xsl:when test="Description"><xsl:value-of select="Description"/></xsl:when>
                    <xsl:otherwise><xsl:value-of select="name()"/> #<xsl:value-of select="position()"/></xsl:otherwise>
                </xsl:choose>
            </Name>
            <Parents>
                <Parent><xsl:value-of select="name(parent::*)"/></Parent>
            </Parents>
            <MetricValues>
                <xsl:choose>
                    <!--Sometimes test cases have no children and the data in the element is the only metric.-->
                    <xsl:when test="count(*)=0">
                        <xsl:call-template name="MetricValue"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:for-each select="*[count(*)=0]">
                            <xsl:call-template name="MetricValue"/>
                        </xsl:for-each>
                        <xsl:if test="$nesting&gt;1">
                            <xsl:for-each select="*/*[count(*)=0]">
                                <xsl:call-template name="MetricValue"/>
                            </xsl:for-each>
                        </xsl:if>
                    </xsl:otherwise>
                </xsl:choose>
            </MetricValues>
        </TestCase>
    </xsl:template>
    
</xsl:transform>