<xsl:stylesheet version="1.0" xmlns:oval-def="http://oval.mitre.org/XMLSchema/oval-definitions-5"
    xmlns:unix-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:cdf="http://checklists.nist.gov/xccdf/1.1" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:oval-res="http://oval.mitre.org/XMLSchema/oval-results-5"
    xmlns:oval-sc="http://oval.mitre.org/XMLSchema/oval-system-characteristics-5"
    xmlns:unix-sc="http://oval.mitre.org/XMLSchema/oval-system-characteristics-5#unix"
    exclude-result-prefixes="oval-def xsl cdf xsd oval-res oval-sc unix-sc unix-def">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    
    <xsl:param name="defid" />
    <xsl:template match="/">
        <xsl:call-template name="getFindings">
            <xsl:with-param name="definitionId" select="$defid" />
        </xsl:call-template>
    </xsl:template>
	
    <!-- IT IS ASSUMED THAT FILE/DIRECTORY NAME WOULD BE AFTER HYPHEN IN THE TITLE -->
    <xsl:template name="getFileNameFromTitle">
        <xsl:param name="title"/>        
        <xsl:variable name="fileName">
            <xsl:if test="contains($title, '-' )">
                <xsl:value-of select="substring-after($title, '-' )"/>
            </xsl:if>          
        </xsl:variable>        
        <xsl:choose>            
            <xsl:when test="$fileName != '' ">
                <xsl:value-of select="$fileName"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$title"/>
            </xsl:otherwise>
        </xsl:choose>        
    </xsl:template>
    
    <xsl:template name="getOwnerTypeFromTitle">
        <xsl:param name="title"/>
        <xsl:variable name="subTitle">
            <xsl:if test="contains($title, '-' )">
                <xsl:value-of select="substring-before($title, '-' )"/>
            </xsl:if>
        </xsl:variable>
        <xsl:variable name="ownerType">
            <xsl:choose>            
                <xsl:when test="contains($subTitle, 'permissions' )">
                    <xsl:text>permissions</xsl:text>                    
                </xsl:when>
                <xsl:when test="contains($subTitle, 'group' )">
                    <xsl:text>group</xsl:text>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:text>user</xsl:text>
                </xsl:otherwise>
            </xsl:choose>            
        </xsl:variable>        
        <xsl:choose>            
            <xsl:when test="$ownerType != '' ">
                <xsl:value-of select="$ownerType"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$title"/>
            </xsl:otherwise>
        </xsl:choose>        
    </xsl:template>
    
    <xsl:template name="getFileTypeFromTitle">
        <xsl:param name="title"/>        
        <xsl:variable name="fileType">
            <xsl:choose>
                <xsl:when test="contains($title, 'directory' )">
                    <xsl:text>directory</xsl:text>
                </xsl:when>
                <xsl:when test="contains($title, 'directories' )">
                    <xsl:text>directories</xsl:text>
                </xsl:when>
                <xsl:when test="contains($title, 'files' )">
                    <xsl:text>files</xsl:text>
                </xsl:when>
                <xsl:when test="contains($title, 'file' )">
                    <xsl:text>file</xsl:text>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:text>file or directory</xsl:text>
                </xsl:otherwise>
            </xsl:choose>            
        </xsl:variable>        
        <xsl:choose>            
            <xsl:when test="$fileType != '' ">
                <xsl:value-of select="$fileType"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$title"/>
            </xsl:otherwise>
        </xsl:choose>        
    </xsl:template>
    
    <!--  Convert binary to Octal value -->
    <xsl:template name="convertBinaryToOctal">
        <xsl:param name="value"/>        
        <xsl:variable name="octalVal">
            <xsl:choose>            
                <xsl:when test="contains($value, '000' )">
                    <xsl:text>0</xsl:text>                    
                </xsl:when>
                <xsl:when test="contains($value, '001' )">
                    <xsl:text>1</xsl:text>                    
                </xsl:when>
                <xsl:when test="contains($value, '010' )">
                    <xsl:text>2</xsl:text>                    
                </xsl:when>
                <xsl:when test="contains($value, '011' )">
                    <xsl:text>3</xsl:text>                    
                </xsl:when>
                <xsl:when test="contains($value, '100' )">
                    <xsl:text>4</xsl:text>                    
                </xsl:when>
                <xsl:when test="contains($value, '101' )">
                    <xsl:text>5</xsl:text>                    
                </xsl:when>
                <xsl:when test="contains($value, '110' )">
                    <xsl:text>6</xsl:text>                    
                </xsl:when>
                <xsl:when test="contains($value, '111' )">
                    <xsl:text>7</xsl:text>                    
                </xsl:when>
                <xsl:otherwise>
                    <xsl:text>0</xsl:text>
                </xsl:otherwise>
            </xsl:choose>            
        </xsl:variable>        
        <xsl:choose>            
            <xsl:when test="$octalVal != '' ">
                <xsl:value-of select="$octalVal"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$value"/>
            </xsl:otherwise>
        </xsl:choose>        
    </xsl:template>
    
    <xsl:template name="getFindings">
        <xsl:param name="definitionId"/>
        <xsl:variable name="result" select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:definitions/oval-res:definition[@definition_id=$definitionId]/@result"/>
        <xsl:variable name="Definitions" select="/oval-res:oval_results/oval-def:oval_definitions/oval-def:definitions"/>
        <xsl:variable name="title" select="$Definitions/oval-def:definition[ @id = $definitionId ]/oval-def:metadata/oval-def:title"/>
        
        <!-- Collect all results for the criterias in the variables ......................................... --> 
        <xsl:variable name="result1" select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:definitions/oval-res:definition[@definition_id=$definitionId]/descendant::oval-res:criterion[1]/@result"/>
        <xsl:variable name="result2" select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:definitions/oval-res:definition[@definition_id=$definitionId]/descendant::oval-res:criterion[2]/@result"/>
        <xsl:variable name="result3" select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:definitions/oval-res:definition[@definition_id=$definitionId]/descendant::oval-res:criterion[3]/@result"/>
        
        <xsl:variable name="result4" select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:definitions/oval-res:definition[@definition_id=$definitionId]/descendant::oval-res:criterion[4]/@result"/>  
        <xsl:variable name="result5" select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:definitions/oval-res:definition[@definition_id=$definitionId]/descendant::oval-res:criterion[5]/@result"/>
        <xsl:variable name="result6" select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:definitions/oval-res:definition[@definition_id=$definitionId]/descendant::oval-res:criterion[6]/@result"/>
        
        <xsl:variable name="testId1" select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:definitions/oval-res:definition[@definition_id=$definitionId]/descendant::oval-res:criterion[3]/@test_ref"/>
        <xsl:variable name="testId2" select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:definitions/oval-res:definition[@definition_id=$definitionId]/descendant::oval-res:criterion[6]/@test_ref"/>
        
        <xsl:variable name="testId">
            <xsl:choose>            
                <xsl:when test="$result1=false">
                    <xsl:value-of select="$testId2"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$testId1"/>
                </xsl:otherwise>
            </xsl:choose>        
        </xsl:variable>
                
        <!-- Check which kind of owner permissions are being tested in this check ........................................................................................... -->
        <xsl:variable name="ownerType">
            <xsl:call-template name="getOwnerTypeFromTitle">
                <xsl:with-param name="title" select="$title"/>            
            </xsl:call-template>                
        </xsl:variable>
        
        <xsl:variable name="testedVar" select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:tests/oval-res:test[@test_id=$testId]"/>
        
        <xsl:variable name="octalVal1">
            <xsl:call-template name="convertBinaryToOctal">
                <xsl:with-param name="value" select="  concat($testedVar/oval-res:tested_variable[1], $testedVar/oval-res:tested_variable[2], $testedVar/oval-res:tested_variable[3])"/>
            </xsl:call-template>            
        </xsl:variable>
        <xsl:variable name="octalVal2">
            <xsl:call-template name="convertBinaryToOctal">
                <xsl:with-param name="value" select="  concat($testedVar/oval-res:tested_variable[4], $testedVar/oval-res:tested_variable[5], $testedVar/oval-res:tested_variable[6])"/>
            </xsl:call-template>                
        </xsl:variable>
        <xsl:variable name="octalVal3">
            <xsl:call-template name="convertBinaryToOctal">
                <xsl:with-param name="value" select="  concat($testedVar/oval-res:tested_variable[7], $testedVar/oval-res:tested_variable[8], $testedVar/oval-res:tested_variable[9])"/>            
            </xsl:call-template>
        </xsl:variable>
        
        <xsl:variable name="binaryValue">
            <xsl:value-of select="concat($testedVar/oval-res:tested_variable[1],
                $testedVar/oval-res:tested_variable[2], 
                $testedVar/oval-res:tested_variable[3], ',' ,
                $testedVar/oval-res:tested_variable[4], 
                $testedVar/oval-res:tested_variable[5],
                $testedVar/oval-res:tested_variable[6], ',' ,
                $testedVar/oval-res:tested_variable[7], 
                $testedVar/oval-res:tested_variable[8], 
                $testedVar/oval-res:tested_variable[9])"/>
        </xsl:variable>
            
        <!--  Extract input value -->
        <xsl:variable name="externalVarValue">
            <xsl:choose>
                <xsl:when test="contains($ownerType, 'group') ">
                    <xsl:value-of select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:tests/oval-res:test[@test_id=$testId]/oval-res:tested_variable[1]"/>                                             
                </xsl:when>
                <xsl:when test="contains($ownerType,'user') ">
                    <xsl:value-of select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:tests/oval-res:test[@test_id=$testId]/oval-res:tested_variable[1]"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:variable name="octalVal" select="concat($octalVal1, $octalVal2, $octalVal3) ">                     
                    </xsl:variable>                    
                    <xsl:value-of select="concat($octalVal, ' (', $binaryValue, ')' )"/>                    
                </xsl:otherwise>
            </xsl:choose>           
        </xsl:variable>             
        
        <xsl:variable name="testedVarCount">
            <xsl:value-of select="count(/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:tests/oval-res:test[@test_id=$testId]/oval-res:tested_variable)"/>
        </xsl:variable>        
        <xsl:variable name="fileItemCount">
            <xsl:value-of select="count(/oval-res:oval_results/oval-res:results/oval-res:system/oval-sc:oval_system_characteristics/oval-sc:system_data/unix-sc:file_item)"/>
        </xsl:variable>        
        
        <!-- Verify the check is for File or Directory ........................................................................................... -->
        <xsl:variable name="fileType">
            <xsl:call-template name="getFileTypeFromTitle">
                <xsl:with-param name="title" select="$title"/>            
            </xsl:call-template>                
        </xsl:variable>

        <!-- Verify the actual permissions value existing on the system........................................................................................... -->
        <xsl:variable name="fileTestItem_id" select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:tests/oval-res:test[@test_id=$testId]/oval-res:tested_item/@item_id"/>
        <xsl:variable name="item" select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-sc:oval_system_characteristics/oval-sc:system_data/unix-sc:file_item[@id=$fileTestItem_id]"/>        
        
        <!-- Extract actual value -->
        <xsl:variable name="systemValue">
            <xsl:choose>
                <xsl:when test="contains($ownerType, 'group') ">
                    <xsl:value-of select="$item/unix-sc:group_id/text()"/>                                             
                </xsl:when>
                <xsl:when test="contains($ownerType,'user') ">
                    <xsl:value-of select="$item/unix-sc:user_id/text()"/>
                </xsl:when>
                <xsl:otherwise>
                    <!-- extract octal value in case of permissions -->
                    <xsl:variable name="actualBinaryValue" select="concat( $item/unix-sc:uread/text(), 
                        $item/unix-sc:uwrite/text(), 
                        $item/unix-sc:uexec/text(), ',',
                        $item/unix-sc:gread/text(), 
                        $item/unix-sc:gwrite/text(), 
                        $item/unix-sc:gexec/text(), ',',
                        $item/unix-sc:oread/text(), 
                        $item/unix-sc:owrite/text(), 
                        $item/unix-sc:oexec/text() )">
                    </xsl:variable>
                    <xsl:variable name="actualOctalVal1">
                        <xsl:call-template name="convertBinaryToOctal">
                            <xsl:with-param name="value" select="  concat($item/unix-sc:uread/text(), 
                                $item/unix-sc:uwrite/text(), 
                                $item/unix-sc:uexec/text())"/>            
                        </xsl:call-template>                
                    </xsl:variable>                    
                    <xsl:variable name="actualOctalVal2">
                        <xsl:call-template name="convertBinaryToOctal">
                            <xsl:with-param name="value" select="  concat($item/unix-sc:gread/text(), 
                                $item/unix-sc:gwrite/text(), 
                                $item/unix-sc:gexec/text())"/>            
                        </xsl:call-template>                
                    </xsl:variable>
                    <xsl:variable name="actualOctalVal3">
                        <xsl:call-template name="convertBinaryToOctal">
                            <xsl:with-param name="value" select="  concat($item/unix-sc:oread/text(), 
                                $item/unix-sc:owrite/text(), 
                                $item/unix-sc:oexec/text())"/>            
                        </xsl:call-template>                
                    </xsl:variable>                                        
                    <xsl:value-of select="concat( $actualOctalVal1, $actualOctalVal2, $actualOctalVal3, ' (' , $actualBinaryValue, ')' )"/>
                </xsl:otherwise>
            </xsl:choose>           
        </xsl:variable>
        
        <!-- Decide about the message id depending upon  the combination of results for various criterions ........................................................................................... -->
        <!-- Also if permissions are being checked for single file or directory then actual values will also be displayed to user and if multiple files/directories are
        being tested for permissions then general message will be displayed without actual valuese -->
        
        <xsl:variable name="message_id">
        <!-- if number of file items are more than 1 that means permissions are being checked for multiple files/directories-->
        <xsl:choose>
            <!-- if number of file item is one then display specific message with actual values -->
            <xsl:when test="$fileItemCount = 1">
                <!-- Check if result is true ........................................................................................... -->
                <xsl:if test="$result='true'">
                    <xsl:choose>
                        <xsl:when test="$result2 = 'true' or $result5='true'">
                            <xsl:text>com.mcafee.pa.msg.FileDoesNotExist</xsl:text>
                        </xsl:when>
                        <xsl:when test="$result2 = 'false' or $result5='false'">
                            <xsl:choose>
                                <xsl:when test="contains($ownerType, 'group' )">
                                    <xsl:text>com.mcafee.pa.msg.FileGroupOwnerValid</xsl:text>
                                </xsl:when>
                                <xsl:when test="contains($ownerType, 'user') ">
                                    <xsl:text>com.mcafee.pa.msg.FileUserOwnerValid</xsl:text>
                                </xsl:when>
                                <xsl:otherwise>
                                    <xsl:text>com.mcafee.pa.msg.FilePermissionsValid</xsl:text> 
                                </xsl:otherwise>
                            </xsl:choose>
                        </xsl:when>
                    </xsl:choose>
                </xsl:if>
                <!-- Check if result is false ........................................................................................... -->
                <xsl:if test="$result='false'">
                    <xsl:choose>
                        <xsl:when test="contains($ownerType, 'group') ">
                            <xsl:text>com.mcafee.pa.msg.FileGroupOwnerValid</xsl:text>
                        </xsl:when>
                        <xsl:when test="contains($ownerType, 'user' ) ">
                            <xsl:text>com.mcafee.pa.msg.FileUserOwnerValid</xsl:text>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:text>com.mcafee.pa.msg.FilePermissionsValid</xsl:text>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:if>
            </xsl:when>
             <!-- For multiple files/directories display general message-->
            <xsl:otherwise>
                <!-- Check if result is true ........................................................................................... -->
                <xsl:if test="$result='true'">
                    <xsl:choose>
                        <xsl:when test="$result2 = 'true' or $result5='true'">
                            <xsl:text>com.mcafee.pa.msg.FileDoesNotExist</xsl:text>
                        </xsl:when>
                        <xsl:when test="$result3 = 'true' or $result6='true'">
                            <xsl:choose>
                                <xsl:when test="contains($ownerType, 'group' )">
                                    <xsl:text>com.mcafee.pa.msg.FileGroupOwnerValidGeneral</xsl:text>
                                </xsl:when>
                                <xsl:when test="contains($ownerType, 'user') ">
                                    <xsl:text>com.mcafee.pa.msg.FileUserOwnerValidGeneral</xsl:text>
                                </xsl:when>
                                <xsl:otherwise>
                                    <xsl:text>com.mcafee.pa.msg.FilePermissionsValidGeneral</xsl:text> 
                                </xsl:otherwise>
                            </xsl:choose>
                        </xsl:when>
                    </xsl:choose>
                </xsl:if>
                <!-- Check if result is false ........................................................................................... -->
                <xsl:if test="$result='false'">
                    <xsl:choose>
                        <xsl:when test="contains($ownerType, 'group') ">
                            <xsl:text>com.mcafee.pa.msg.FileGroupOwnerValidGeneral</xsl:text> 
                        </xsl:when>
                        <xsl:when test="contains($ownerType, 'user' ) ">
                            <xsl:text>com.mcafee.pa.msg.FileUserOwnerValidGeneral</xsl:text>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:text>com.mcafee.pa.msg.FilePermissionsValidGeneral</xsl:text>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:if>
            </xsl:otherwise>
        </xsl:choose>
        </xsl:variable>
        
        <xsl:variable name="isViolationValue">
            <xsl:choose>
                <xsl:when test="$result = 'false' ">
                    <xsl:text>true</xsl:text>                                              
                </xsl:when>
                <xsl:when test="$result = 'true' ">
                    <xsl:text>false</xsl:text>                                              
                </xsl:when>
            </xsl:choose>               
        </xsl:variable>
        
        <xsl:variable name="fileName">
            <xsl:call-template name="getFileNameFromTitle">
                <xsl:with-param name="title" select="$title"/>            
            </xsl:call-template>
        </xsl:variable>
        
        <xsl:element name="findings" namespace="http://results.pa.mcafee.com/findings/5.2">
            <xsl:attribute name="id">
                <xsl:value-of select="$definitionId"/>
            </xsl:attribute>
            <xsl:element name="inputValue" namespace="http://results.pa.mcafee.com/findings/5.2">
                <xsl:attribute name="key">UserValue</xsl:attribute>
                <xsl:value-of select="$externalVarValue"/>
            </xsl:element>
            <xsl:element name="finding" namespace="http://results.pa.mcafee.com/findings/5.2" >
                <xsl:attribute name="messageId">
                    <xsl:value-of select="$message_id"/>
                </xsl:attribute>
                <xsl:attribute name="isViolation">
                    <xsl:value-of select="$isViolationValue"/>
                </xsl:attribute>
                <xsl:element name="actualValue" namespace="http://results.pa.mcafee.com/findings/5.2">
                    <xsl:attribute name="key">SystemValue</xsl:attribute>
                    <xsl:value-of select="$systemValue"/>
                </xsl:element>
                <xsl:element name="instanceValue" namespace="http://results.pa.mcafee.com/findings/5.2">
                    <xsl:attribute name="key">FileName</xsl:attribute>
                    <xsl:value-of select="$fileName"/>
                </xsl:element>                
                <xsl:element name="instanceValue" namespace="http://results.pa.mcafee.com/findings/5.2">
                    <xsl:attribute name="key">FileType</xsl:attribute>
                    <xsl:value-of select="$fileType"/>
                </xsl:element>
            </xsl:element>
        </xsl:element>
                
    </xsl:template>
</xsl:stylesheet>