## @file
# This file is used to create report for Eot tool
#
# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#

##
# Import Modules
#
from __future__ import absolute_import
import Common.LongFilePathOs as os
from . import EotGlobalData
from Common.LongFilePathSupport import OpenLongFilePath as open

## Report() class
#
#  This class defined Report
#
#  @param object: Inherited from object class
#
class Report(object):
    ## The constructor
    #
    #  @param  self: The object pointer
    #  @param  ReportName: name of the report
    #  @param  FvObj: FV object after parsing FV images
    #
    def __init__(self, ReportName = 'Report.html', FvObj = None, DispatchName=None):
        self.ReportName = ReportName
        self.Op = open(ReportName, 'w+')
        self.DispatchList = None
        if DispatchName:
            self.DispatchList = open(DispatchName, 'w+')
        self.FvObj = FvObj
        self.FfsIndex = 0
        self.PpiIndex = 0
        self.ProtocolIndex = 0
        if EotGlobalData.gMACRO['EFI_SOURCE'] == '':
            EotGlobalData.gMACRO['EFI_SOURCE'] = EotGlobalData.gMACRO['EDK_SOURCE']

    ## WriteLn() method
    #
    #  Write a line in the report
    #
    #  @param  self: The object pointer
    #  @param Line:  The lint to be written into
    #
    def WriteLn(self, Line):
        self.Op.write('%s\n' % Line)

    ## GenerateReport() method
    #
    #  A caller to generate report
    #
    #  @param  self: The object pointer
    #
    def GenerateReport(self):
        self.GenerateHeader()
        self.GenerateFv()
        self.GenerateTail()
        self.Op.close()
        self.GenerateUnDispatchedList()

    ## GenerateUnDispatchedList() method
    #
    #  Create a list for not dispatched items
    #
    #  @param  self: The object pointer
    #
    def GenerateUnDispatchedList(self):
        FvObj = self.FvObj
        EotGlobalData.gOP_UN_DISPATCHED.write('%s\n' % FvObj.Name)
        for Item in FvObj.UnDispatchedFfsDict.keys():
            EotGlobalData.gOP_UN_DISPATCHED.write('%s\n' % FvObj.UnDispatchedFfsDict[Item])

    ## GenerateFv() method
    #
    #  Generate FV information
    #
    #  @param  self: The object pointer
    #
    def GenerateFv(self):
        FvObj = self.FvObj
        Content = """  <tr>
    <td width="20%%"><strong>Name</strong></td>
    <td width="60%%"><strong>Guid</strong></td>
    <td width="20%%"><strong>Size</strong></td>
  </tr>"""
        self.WriteLn(Content)

        for Info in FvObj.BasicInfo:
            FvName = Info[0]
            FvGuid = Info[1]
            FvSize = Info[2]

            Content = """  <tr>
    <td>%s</td>
    <td>%s</td>
    <td>%s</td>
  </tr>"""  % (FvName, FvGuid, FvSize)
            self.WriteLn(Content)

        Content = """    <td colspan="3"><table width="100%%"  border="1">
      <tr>"""
        self.WriteLn(Content)

        EotGlobalData.gOP_DISPATCH_ORDER.write('Dispatched:\n')
        for FfsId in FvObj.OrderedFfsDict.keys():
            self.GenerateFfs(FvObj.OrderedFfsDict[FfsId])
        Content = """     </table></td>
  </tr>"""
        self.WriteLn(Content)

        # For UnDispatched
        Content = """    <td colspan="3"><table width="100%%"  border="1">
      <tr>
        <tr><strong>UnDispatched</strong></tr>"""
        self.WriteLn(Content)

        EotGlobalData.gOP_DISPATCH_ORDER.write('\nUnDispatched:\n')
        for FfsId in FvObj.UnDispatchedFfsDict.keys():
            self.GenerateFfs(FvObj.UnDispatchedFfsDict[FfsId])
        Content = """     </table></td>
  </tr>"""
        self.WriteLn(Content)

    ## GenerateDepex() method
    #
    #  Generate Depex information
    #
    #  @param  self: The object pointer
    #  @param DepexString: A DEPEX string needed to be parsed
    #
    def GenerateDepex(self, DepexString):
        NonGuidList = ['AND', 'OR', 'NOT', 'BEFORE', 'AFTER', 'TRUE', 'FALSE']
        ItemList = DepexString.split(' ')
        DepexString = ''
        for Item in ItemList:
            if Item not in NonGuidList:
                SqlCommand = """select DISTINCT GuidName from Report where GuidValue like '%s' and ItemMode = 'Produced' group by GuidName""" % (Item)
                RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
                if RecordSet != []:
                    Item = RecordSet[0][0]
            DepexString = DepexString + Item + ' '
        Content = """                <tr>
                  <td width="5%%"></td>
                  <td width="95%%">%s</td>
                </tr>""" % (DepexString)
        self.WriteLn(Content)

    ## GeneratePpiProtocol() method
    #
    #  Generate PPI/PROTOCOL information
    #
    #  @param self: The object pointer
    #  @param Model: Model of a GUID, PPI or PROTOCOL
    #  @param Name: Name of a GUID
    #  @param Guid: Value of a GUID
    #  @param Type: Type of a GUID
    #  @param CName: CName(Index) of a GUID
    #
    def GeneratePpiProtocol(self, Model, Name, Guid, Type, CName):
        Content = """                <tr>
                  <td width="5%%"></td>
                  <td width="10%%">%s</td>
                  <td width="85%%" colspan="3">%s</td>
                  <!-- %s -->
                </tr>""" % (Model, Name, Guid)
        self.WriteLn(Content)
        if Type == 'Produced':
            SqlCommand = """select DISTINCT SourceFileFullPath, BelongsToFunction from Report where GuidName like '%s' and ItemMode = 'Callback'""" % Name
            RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
            for Record in RecordSet:
                SqlCommand = """select FullPath from File
                                where ID = (
                                select DISTINCT BelongsToFile from Inf
                                where Value1 like '%s')""" % Record[0]
                ModuleSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
                Inf = ModuleSet[0][0].replace(EotGlobalData.gMACRO['WORKSPACE'], '.')
                Function = Record[1]
                Address = ''
                for Item in EotGlobalData.gMap:
                    if Function in EotGlobalData.gMap[Item]:
                        Address = EotGlobalData.gMap[Item][Function]
                        break
                    if '_' + Function in EotGlobalData.gMap[Item]:
                        Address = EotGlobalData.gMap[Item]['_' + Function]
                        break
                Content = """                <tr>
                      <td width="5%%"></td>
                      <td width="10%%">%s</td>
                      <td width="40%%">%s</td>
                      <td width="35%%">%s</td>
                      <td width="10%%">%s</td>
                    </tr>""" % ('Callback', Inf, Function, Address)
                self.WriteLn(Content)

    ## GenerateFfs() method
    #
    #  Generate FFS information
    #
    #  @param self: The object pointer
    #  @param FfsObj: FFS object after FV image is parsed
    #
    def GenerateFfs(self, FfsObj):
        self.FfsIndex = self.FfsIndex + 1
        if FfsObj is not None and FfsObj.Type in [0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0xA]:
            FfsGuid = FfsObj.Guid
            FfsOffset = FfsObj._OFF_
            FfsName = 'Unknown-Module'
            FfsPath = FfsGuid
            FfsType = FfsObj._TypeName[FfsObj.Type]

            # Hard code for Binary INF
            if FfsGuid.upper() == '7BB28B99-61BB-11D5-9A5D-0090273FC14D':
                FfsName = 'Logo'

            if FfsGuid.upper() == '7E374E25-8E01-4FEE-87F2-390C23C606CD':
                FfsName = 'AcpiTables'

            if FfsGuid.upper() == '961578FE-B6B7-44C3-AF35-6BC705CD2B1F':
                FfsName = 'Fat'

            # Find FFS Path and Name
            SqlCommand = """select Value2 from Inf
                            where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
                            and Model = %s and Value1='BASE_NAME'""" % (FfsGuid, 5001, 5001)
            RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
            if RecordSet != []:
                FfsName = RecordSet[0][0]

            SqlCommand = """select FullPath from File
                            where ID = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
                            and Model = %s""" % (FfsGuid, 5001, 1011)
            RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
            if RecordSet != []:
                FfsPath = RecordSet[0][0]

            Content = """  <tr>
      <tr class='styleFfs' id='FfsHeader%s'>
        <td width="55%%"><span onclick="Display('FfsHeader%s', 'Ffs%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">%s</span></td>
        <td width="15%%">%s</td>
        <!--<td width="20%%">%s</td>-->
        <!--<td width="20%%">%s</td>-->
        <td width="10%%">%s</td>
      </tr>
      <tr id='Ffs%s' style='display:none;'>
        <td colspan="4"><table width="100%%"  border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, FfsPath, FfsName, FfsGuid, FfsOffset, FfsType, self.FfsIndex)

            if self.DispatchList:
                if FfsObj.Type in [0x04, 0x06]:
                    self.DispatchList.write("%s %s %s %s\n" % (FfsGuid, "P", FfsName, FfsPath))
                if FfsObj.Type in [0x05, 0x07, 0x08, 0x0A]:
                    self.DispatchList.write("%s %s %s %s\n" % (FfsGuid, "D", FfsName, FfsPath))

            self.WriteLn(Content)

            EotGlobalData.gOP_DISPATCH_ORDER.write('%s\n' %FfsName)

            if FfsObj.Depex != '':
                Content = """          <tr>
            <td><span id='DepexHeader%s' class="styleDepex" onclick="Display('DepexHeader%s', 'Depex%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">&nbsp&nbspDEPEX expression</span></td>
          </tr>
          <tr id='Depex%s' style='display:none;'>
            <td><table width="100%%"  border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, self.FfsIndex)
                self.WriteLn(Content)
                self.GenerateDepex(FfsObj.Depex)
                Content = """            </table></td>
          </tr>"""
                self.WriteLn(Content)
            # End of DEPEX

            # Find Consumed Ppi/Protocol
            SqlCommand = """select ModuleName, ItemType, GuidName, GuidValue, GuidMacro from Report
                            where SourceFileFullPath in
                            (select Value1 from Inf where BelongsToFile =
                            (select BelongsToFile from Inf
                            where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
                            and Model = %s)
                            and ItemMode = 'Consumed' group by GuidName order by ItemType""" \
                            % (FfsGuid, 5001, 3007)

            RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
            if RecordSet != []:
                Count = len(RecordSet)
                Content = """          <tr>
            <td><span id='ConsumedHeader%s' class="styleConsumed" onclick="Display('ConsumedHeader%s', 'Consumed%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">&nbsp&nbspConsumed Ppis/Protocols List (%s)</span></td>
          </tr>
          <tr id='Consumed%s' style='display:none;'>
            <td><table width="100%%"  border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, Count, self.FfsIndex)
                self.WriteLn(Content)
                self.ProtocolIndex = 0
                for Record in RecordSet:
                    self.ProtocolIndex = self.ProtocolIndex + 1
                    Name = Record[2]
                    CName = Record[4]
                    Guid = Record[3]
                    Type = Record[1]
                    self.GeneratePpiProtocol(Type, Name, Guid, 'Consumed', CName)

                Content = """            </table></td>
          </tr>"""
                self.WriteLn(Content)
            #End of Consumed Ppi/Protocol

            # Find Produced Ppi/Protocol
            SqlCommand = """select ModuleName, ItemType, GuidName, GuidValue, GuidMacro from Report
                            where SourceFileFullPath in
                            (select Value1 from Inf where BelongsToFile =
                            (select BelongsToFile from Inf
                            where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
                            and Model = %s)
                            and ItemMode = 'Produced' group by GuidName order by ItemType""" \
                            % (FfsGuid, 5001, 3007)

            RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
            if RecordSet != []:
                Count = len(RecordSet)
                Content = """          <tr>
            <td><span id='ProducedHeader%s' class="styleProduced" onclick="Display('ProducedHeader%s', 'Produced%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">&nbsp&nbspProduced Ppis/Protocols List (%s)</span></td>
          </tr>
          <tr id='Produced%s' style='display:none;'>
            <td><table width="100%%"  border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, Count, self.FfsIndex)
                self.WriteLn(Content)
                self.PpiIndex = 0
                for Record in RecordSet:
                    self.PpiIndex = self.PpiIndex + 1
                    Name = Record[2]
                    CName = Record[4]
                    Guid = Record[3]
                    Type = Record[1]
                    self.GeneratePpiProtocol(Type, Name, Guid, 'Produced', CName)

                Content = """            </table></td>
          </tr>"""
                self.WriteLn(Content)
            RecordSet = None
            # End of Produced Ppi/Protocol

            Content = """        </table></td>
        </tr>"""
            self.WriteLn(Content)

    ## GenerateTail() method
    #
    #  Generate end tags of HTML report
    #
    #  @param self: The object pointer
    #
    def GenerateTail(self):
        Tail = """</table>
</body>
</html>"""
        self.WriteLn(Tail)

    ## GenerateHeader() method
    #
    #  Generate start tags of HTML report
    #
    #  @param self: The object pointer
    #
    def GenerateHeader(self):
        Header = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Execution Order Tool Report</title>
<meta http-equiv="Content-Type" content="text/html">
<style type="text/css">
<!--
.styleFfs {
    color: #006600;
    font-weight: bold;
}
.styleDepex {
    color: #FF0066;
    font-weight: bold;
}
.styleProduced {
    color: #0000FF;
    font-weight: bold;
}
.styleConsumed {
    color: #FF00FF;
    font-weight: bold;
}
-->
</style>
<Script type="text/javascript">
function Display(ParentID, SubID)
{
    SubItem = document.getElementById(SubID);
    ParentItem = document.getElementById(ParentID);
    if (SubItem.style.display == 'none')
    {
        SubItem.style.display = ''
        ParentItem.style.fontWeight = 'normal'
    }
    else
    {
        SubItem.style.display = 'none'
        ParentItem.style.fontWeight = 'bold'
    }

}

function funOnMouseOver()
{
    document.body.style.cursor = "hand";
}

function funOnMouseOut()
{
    document.body.style.cursor = "";
}

</Script>
</head>

<body>
<table width="100%%"  border="1">"""
        self.WriteLn(Header)

##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
    # Initialize log system
    FilePath = 'FVRECOVERYFLOPPY.fv'
    if FilePath.lower().endswith(".fv"):
        fd = open(FilePath, 'rb')
        buf = array('B')
        try:
            buf.fromfile(fd, os.path.getsize(FilePath))
        except EOFError:
            pass

        fv = FirmwareVolume("FVRECOVERY", buf, 0)

    report = Report('Report.html', fv)
    report.GenerateReport()
