## @file
# process GUIDed section generation
#
#  Copyright (c) 2007 - 2010, 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 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

## 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)

            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)

            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 and TempFileSize % 4 == 0:
                    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.WorkSpaceDir).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)
                    
        ToolDefinition = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.WorkSpaceDir).ToolsDefTxtDictionary
        ToolPathTmp = 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))
                            
                    
        return ToolPathTmp, ToolOption



