## @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
from GenFds import FindExtendTool

## 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 = FindExtendTool(self.KeyStringList, self.CurrentArchList, self.NameGuid)

        #
        # 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



