## @file
# process GUIDed section generation
#
#  Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
#
#  This program and the accompanying materials
#  are licensed and made available under the terms and conditions of the BSD License
#  which accompanies this distribution.  The full text of the license may be found at
#  http://opensource.org/licenses/bsd-license.php
#
#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#

##
# Import Modules
#
import Section
import subprocess
from Ffs import Ffs
import Common.LongFilePathOs as os
from GenFdsGlobalVariable import GenFdsGlobalVariable
from CommonDataClass.FdfClass import GuidSectionClassObject
from Common import ToolDefClassObject
import sys
from Common import EdkLogger
from Common.BuildToolError import *
from FvImageSection import FvImageSection
from Common.LongFilePathSupport import OpenLongFilePath as open

## generate GUIDed section
#
#
class GuidSection(GuidSectionClassObject) :

    ## The constructor
    #
    #   @param  self        The object pointer
    #
    def __init__(self):
        GuidSectionClassObject.__init__(self)

    ## GenSection() method
    #
    #   Generate GUIDed section
    #
    #   @param  self        The object pointer
    #   @param  OutputPath  Where to place output file
    #   @param  ModuleName  Which module this section belongs to
    #   @param  SecNum      Index of section
    #   @param  KeyStringList  Filter for inputs of section generation
    #   @param  FfsInf      FfsInfStatement object that contains this section data
    #   @param  Dict        dictionary contains macro and its value
    #   @retval tuple       (Generated file name, section alignment)
    #
    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}):
        #
        # Generate all section
        #
        self.KeyStringList = KeyStringList
        self.CurrentArchList = GenFdsGlobalVariable.ArchList
        if FfsInf != None:
            self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
            self.NameGuid = FfsInf.__ExtendMacro__(self.NameGuid)
            self.SectionType = FfsInf.__ExtendMacro__(self.SectionType)
            self.CurrentArchList = [FfsInf.CurrentArch]

        SectFile = tuple()
        SectAlign = []
        Index = 0
        MaxAlign = None
        if self.FvAddr != []:
            FvAddrIsSet = True
        else:
            FvAddrIsSet = False
        
        if self.ProcessRequired in ("TRUE", "1"):
            if self.FvAddr != []:
                #no use FvAddr when the image is processed.
                self.FvAddr = []
            if self.FvParentAddr != None:
                #no use Parent Addr when the image is processed.
                self.FvParentAddr = None

        for Sect in self.SectionList:
            Index = Index + 1
            SecIndex = '%s.%d' % (SecNum, Index)
            # set base address for inside FvImage
            if isinstance(Sect, FvImageSection):
                if self.FvAddr != []:
                    Sect.FvAddr = self.FvAddr.pop(0)
                self.IncludeFvSection = True
            elif isinstance(Sect, GuidSection):
                Sect.FvAddr = self.FvAddr
                Sect.FvParentAddr = self.FvParentAddr
            ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict)
            if isinstance(Sect, GuidSection):
                if Sect.IncludeFvSection:
                    self.IncludeFvSection = Sect.IncludeFvSection

            if align != None:
                if MaxAlign == None:
                    MaxAlign = align
                if GenFdsGlobalVariable.GetAlignment (align) > GenFdsGlobalVariable.GetAlignment (MaxAlign):
                    MaxAlign = align
            if ReturnSectList != []:
                if align == None:
                    align = "1"
                for file in ReturnSectList:
                    SectFile += (file,)
                    SectAlign.append(align)

        if MaxAlign != None:
            if self.Alignment == None:
                self.Alignment = MaxAlign
            else:
                if GenFdsGlobalVariable.GetAlignment (MaxAlign) > GenFdsGlobalVariable.GetAlignment (self.Alignment):
                    self.Alignment = MaxAlign

        OutputFile = OutputPath + \
                     os.sep + \
                     ModuleName + \
                     'SEC' + \
                     SecNum + \
                     Ffs.SectionSuffix['GUIDED']
        OutputFile = os.path.normpath(OutputFile)

        ExternalTool = None
        ExternalOption = None
        if self.NameGuid != None:
            ExternalTool, ExternalOption = self.__FindExtendTool__()

        #
        # If not have GUID , call default
        # GENCRC32 section
        #
        if self.NameGuid == None :
            GenFdsGlobalVariable.VerboseLogger("Use GenSection function Generate CRC32 Section")
            GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType], InputAlign=SectAlign)
            OutputFileList = []
            OutputFileList.append(OutputFile)
            return OutputFileList, self.Alignment
        #or GUID not in External Tool List
        elif ExternalTool == None:
            EdkLogger.error("GenFds", GENFDS_ERROR, "No tool found with GUID %s" % self.NameGuid)
        else:
            DummyFile = OutputFile + ".dummy"
            #
            # Call GenSection with DUMMY section type.
            #
            GenFdsGlobalVariable.GenerateSection(DummyFile, SectFile, InputAlign=SectAlign)
            #
            # Use external tool process the Output
            #
            TempFile = OutputPath + \
                       os.sep + \
                       ModuleName + \
                       'SEC' + \
                       SecNum + \
                       '.tmp'
            TempFile = os.path.normpath(TempFile)
            #
            # Remove temp file if its time stamp is older than dummy file
            # Just in case the external tool fails at this time but succeeded before
            # Error should be reported if the external tool does not generate a new output based on new input
            #
            if os.path.exists(TempFile) and os.path.exists(DummyFile) and os.path.getmtime(TempFile) < os.path.getmtime(DummyFile):
                os.remove(TempFile)

            FirstCall = False
            CmdOption = '-e'
            if ExternalOption != None:
                CmdOption = CmdOption + ' ' + ExternalOption
            if self.ProcessRequired not in ("TRUE", "1") and self.IncludeFvSection and not FvAddrIsSet and self.FvParentAddr != None:
                #FirstCall is only set for the encapsulated flash FV image without process required attribute.
                FirstCall = True
            #
            # Call external tool
            #
            ReturnValue = [1]
            if FirstCall:
                #first try to call the guided tool with -z option and CmdOption for the no process required guided tool.
                GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, '-z' + ' ' + CmdOption, ReturnValue)

            #
            # when no call or first call failed, ReturnValue are not 1.
            # Call the guided tool with CmdOption
            #
            if ReturnValue[0] != 0:
                FirstCall = False
                ReturnValue[0] = 0
                GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)
            #
            # There is external tool which does not follow standard rule which return nonzero if tool fails
            # The output file has to be checked
            #
            if not os.path.exists(TempFile):
                EdkLogger.error("GenFds", COMMAND_FAILURE, 'Fail to call %s, no output file was generated' % ExternalTool)

            FileHandleIn = open(DummyFile, 'rb')
            FileHandleIn.seek(0, 2)
            InputFileSize = FileHandleIn.tell()

            FileHandleOut = open(TempFile, 'rb')
            FileHandleOut.seek(0, 2)
            TempFileSize = FileHandleOut.tell()

            Attribute = []
            HeaderLength = None
            if self.ExtraHeaderSize != -1:
                HeaderLength = str(self.ExtraHeaderSize)

            if self.ProcessRequired == "NONE" and HeaderLength == None:
                if TempFileSize > InputFileSize:
                    FileHandleIn.seek(0)
                    BufferIn = FileHandleIn.read()
                    FileHandleOut.seek(0)
                    BufferOut = FileHandleOut.read()
                    if BufferIn == BufferOut[TempFileSize - InputFileSize:]:
                        HeaderLength = str(TempFileSize - InputFileSize)
                #auto sec guided attribute with process required
                if HeaderLength == None:
                    Attribute.append('PROCESSING_REQUIRED')

            FileHandleIn.close()
            FileHandleOut.close()

            if FirstCall and 'PROCESSING_REQUIRED' in Attribute:
                # Guided data by -z option on first call is the process required data. Call the guided tool with the real option.
                GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)

            #
            # Call Gensection Add Section Header
            #
            if self.ProcessRequired in ("TRUE", "1"):
                if 'PROCESSING_REQUIRED' not in Attribute:
                    Attribute.append('PROCESSING_REQUIRED')

            if self.AuthStatusValid in ("TRUE", "1"):
                Attribute.append('AUTH_STATUS_VALID')
            GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
                                                 Guid=self.NameGuid, GuidAttr=Attribute, GuidHdrLen=HeaderLength)
            OutputFileList = []
            OutputFileList.append(OutputFile)
            if 'PROCESSING_REQUIRED' in Attribute:
                # reset guided section alignment to none for the processed required guided data
                self.Alignment = None
                self.IncludeFvSection = False
                self.ProcessRequired = "TRUE"
            return OutputFileList, self.Alignment

    ## __FindExtendTool()
    #
    #    Find location of tools to process section data
    #
    #   @param  self        The object pointer
    #
    def __FindExtendTool__(self):
        # if user not specify filter, try to deduce it from global data.
        if self.KeyStringList == None or self.KeyStringList == []:
            Target = GenFdsGlobalVariable.TargetName
            ToolChain = GenFdsGlobalVariable.ToolChainTag
            ToolDb = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDatabase
            if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:
                EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain)
            self.KeyStringList = [Target + '_' + ToolChain + '_' + self.CurrentArchList[0]]
            for Arch in self.CurrentArchList:
                if Target + '_' + ToolChain + '_' + Arch not in self.KeyStringList:
                    self.KeyStringList.append(Target + '_' + ToolChain + '_' + Arch)

        if GenFdsGlobalVariable.GuidToolDefinition:
            if self.NameGuid in GenFdsGlobalVariable.GuidToolDefinition.keys():
                return GenFdsGlobalVariable.GuidToolDefinition[self.NameGuid]

        ToolDefinition = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDictionary
        ToolPathTmp = None
        ToolOption = None
        for ToolDef in ToolDefinition.items():
            if self.NameGuid == ToolDef[1]:
                KeyList = ToolDef[0].split('_')
                Key = KeyList[0] + \
                      '_' + \
                      KeyList[1] + \
                      '_' + \
                      KeyList[2]
                if Key in self.KeyStringList and KeyList[4] == 'GUID':

                    ToolPath = ToolDefinition.get(Key + \
                                                   '_' + \
                                                   KeyList[3] + \
                                                   '_' + \
                                                   'PATH')

                    ToolOption = ToolDefinition.get(Key + \
                                                    '_' + \
                                                    KeyList[3] + \
                                                    '_' + \
                                                    'FLAGS')
                    if ToolPathTmp == None:
                        ToolPathTmp = ToolPath
                    else:
                        if ToolPathTmp != ToolPath:
                            EdkLogger.error("GenFds", GENFDS_ERROR, "Don't know which tool to use, %s or %s ?" % (ToolPathTmp, ToolPath))

        GenFdsGlobalVariable.GuidToolDefinition[self.NameGuid] = (ToolPathTmp, ToolOption)
        return ToolPathTmp, ToolOption



