## @file
# Global variables for GenFds
#
#  Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
#
#  SPDX-License-Identifier: BSD-2-Clause-Patent
#

##
# Import Modules
#
from __future__ import print_function
from __future__ import absolute_import

import Common.LongFilePathOs as os
import sys
from sys import stdout
from subprocess import PIPE,Popen
from struct import Struct
from array import array

from Common.BuildToolError import COMMAND_FAILURE,GENFDS_ERROR
from Common import EdkLogger
from Common.Misc import SaveFileOnChange

from Common.TargetTxtClassObject import TargetTxtDict
from Common.ToolDefClassObject import ToolDefDict,gDefaultToolsDefFile
from AutoGen.BuildEngine import ToolBuildRule
import Common.DataType as DataType
from Common.Misc import PathClass,CreateDirectory
from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
import Common.GlobalData as GlobalData
from Common.BuildToolError import *
from AutoGen.AutoGen import CalculatePriorityValue

## Global variables
#
#
class GenFdsGlobalVariable:
    FvDir = ''
    OutputDirDict = {}
    BinDir = ''
    # will be FvDir + os.sep + 'Ffs'
    FfsDir = ''
    FdfParser = None
    WorkSpace = None
    WorkSpaceDir = ''
    ConfDir = ''
    OutputDirFromDscDict = {}
    TargetName = ''
    ToolChainTag = ''
    RuleDict = {}
    ArchList = None
    ActivePlatform = None
    FvAddressFileName = ''
    VerboseMode = False
    DebugLevel = -1
    SharpCounter = 0
    SharpNumberPerLine = 40
    FdfFile = ''
    FdfFileTimeStamp = 0
    FixedLoadAddress = False
    PlatformName = ''

    BuildRuleFamily = DataType.TAB_COMPILER_MSFT
    ToolChainFamily = DataType.TAB_COMPILER_MSFT
    __BuildRuleDatabase = None
    GuidToolDefinition = {}
    FfsCmdDict = {}
    SecCmdList = []
    CopyList   = []
    ModuleFile = ''
    EnableGenfdsMultiThread = True

    #
    # The list whose element are flags to indicate if large FFS or SECTION files exist in FV.
    # At the beginning of each generation of FV, false flag is appended to the list,
    # after the call to GenerateSection returns, check the size of the output file,
    # if it is greater than 0xFFFFFF, the tail flag in list is set to true,
    # and EFI_FIRMWARE_FILE_SYSTEM3_GUID is passed to C GenFv.
    # At the end of generation of FV, pop the flag.
    # List is used as a stack to handle nested FV generation.
    #
    LargeFileInFvFlags = []
    EFI_FIRMWARE_FILE_SYSTEM3_GUID = '5473C07A-3DCB-4dca-BD6F-1E9689E7349A'
    LARGE_FILE_SIZE = 0x1000000

    SectionHeader = Struct("3B 1B")

    # FvName, FdName, CapName in FDF, Image file name
    ImageBinDict = {}

    ## LoadBuildRule
    #
    @staticmethod
    def _LoadBuildRule():
        if GenFdsGlobalVariable.__BuildRuleDatabase:
            return GenFdsGlobalVariable.__BuildRuleDatabase
        BuildRule = ToolBuildRule()
        GenFdsGlobalVariable.__BuildRuleDatabase = BuildRule.ToolBuildRule
        TargetObj = TargetTxtDict()
        ToolDefinitionFile = TargetObj.Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
        if ToolDefinitionFile == '':
            ToolDefinitionFile =  os.path.join('Conf', gDefaultToolsDefFile)
        if os.path.isfile(ToolDefinitionFile):
            ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf")))
            ToolDefinition = ToolDefObj.ToolDef.ToolsDefTxtDatabase
            if DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDefinition \
               and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY] \
               and ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]:
                GenFdsGlobalVariable.BuildRuleFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]

            if DataType.TAB_TOD_DEFINES_FAMILY in ToolDefinition \
               and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY] \
               and ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]:
                GenFdsGlobalVariable.ToolChainFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]
        return GenFdsGlobalVariable.__BuildRuleDatabase

    ## GetBuildRules
    #    @param Inf: object of InfBuildData
    #    @param Arch: current arch
    #
    @staticmethod
    def GetBuildRules(Inf, Arch):
        if not Arch:
            Arch = DataType.TAB_COMMON

        if not Arch in GenFdsGlobalVariable.OutputDirDict:
            return {}

        BuildRuleDatabase = GenFdsGlobalVariable._LoadBuildRule()
        if not BuildRuleDatabase:
            return {}

        PathClassObj = PathClass(Inf.MetaFile.File,
                                 GenFdsGlobalVariable.WorkSpaceDir)
        BuildDir = os.path.join(
            GenFdsGlobalVariable.OutputDirDict[Arch],
            Arch,
            PathClassObj.SubDir,
            PathClassObj.BaseName
        )
        BinDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)
        Macro = {
        "WORKSPACE":GenFdsGlobalVariable.WorkSpaceDir,
        "MODULE_NAME":Inf.BaseName,
        "MODULE_GUID":Inf.Guid,
        "MODULE_VERSION":Inf.Version,
        "MODULE_TYPE":Inf.ModuleType,
        "MODULE_FILE":str(PathClassObj),
        "MODULE_FILE_BASE_NAME":PathClassObj.BaseName,
        "MODULE_RELATIVE_DIR":PathClassObj.SubDir,
        "MODULE_DIR":PathClassObj.SubDir,
        "BASE_NAME":Inf.BaseName,
        "ARCH":Arch,
        "TOOLCHAIN":GenFdsGlobalVariable.ToolChainTag,
        "TOOLCHAIN_TAG":GenFdsGlobalVariable.ToolChainTag,
        "TOOL_CHAIN_TAG":GenFdsGlobalVariable.ToolChainTag,
        "TARGET":GenFdsGlobalVariable.TargetName,
        "BUILD_DIR":GenFdsGlobalVariable.OutputDirDict[Arch],
        "BIN_DIR":BinDir,
        "LIB_DIR":BinDir,
        "MODULE_BUILD_DIR":BuildDir,
        "OUTPUT_DIR":os.path.join(BuildDir, "OUTPUT"),
        "DEBUG_DIR":os.path.join(BuildDir, "DEBUG")
        }

        BuildRules = {}
        for Type in BuildRuleDatabase.FileTypeList:
            #first try getting build rule by BuildRuleFamily
            RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.BuildRuleFamily]
            if not RuleObject:
                # build type is always module type, but ...
                if Inf.ModuleType != Inf.BuildType:
                    RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.BuildRuleFamily]
            #second try getting build rule by ToolChainFamily
            if not RuleObject:
                RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.ToolChainFamily]
                if not RuleObject:
                    # build type is always module type, but ...
                    if Inf.ModuleType != Inf.BuildType:
                        RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.ToolChainFamily]
            if not RuleObject:
                continue
            RuleObject = RuleObject.Instantiate(Macro)
            BuildRules[Type] = RuleObject
            for Ext in RuleObject.SourceFileExtList:
                BuildRules[Ext] = RuleObject
        return BuildRules

    ## GetModuleCodaTargetList
    #
    #    @param Inf: object of InfBuildData
    #    @param Arch: current arch
    #
    @staticmethod
    def GetModuleCodaTargetList(Inf, Arch):
        BuildRules = GenFdsGlobalVariable.GetBuildRules(Inf, Arch)
        if not BuildRules:
            return []

        TargetList = set()
        FileList = []

        if not Inf.IsBinaryModule:
            for File in Inf.Sources:
                if File.TagName in {"", DataType.TAB_STAR, GenFdsGlobalVariable.ToolChainTag} and \
                    File.ToolChainFamily in {"", DataType.TAB_STAR, GenFdsGlobalVariable.ToolChainFamily}:
                    FileList.append((File, DataType.TAB_UNKNOWN_FILE))

        for File in Inf.Binaries:
            if File.Target in {DataType.TAB_COMMON, DataType.TAB_STAR, GenFdsGlobalVariable.TargetName}:
                FileList.append((File, File.Type))

        for File, FileType in FileList:
            LastTarget = None
            RuleChain = []
            SourceList = [File]
            Index = 0
            while Index < len(SourceList):
                Source = SourceList[Index]
                Index = Index + 1

                if File.IsBinary and File == Source and Inf.Binaries and File in Inf.Binaries:
                    # Skip all files that are not binary libraries
                    if not Inf.LibraryClass:
                        continue
                    RuleObject = BuildRules[DataType.TAB_DEFAULT_BINARY_FILE]
                elif FileType in BuildRules:
                    RuleObject = BuildRules[FileType]
                elif Source.Ext in BuildRules:
                    RuleObject = BuildRules[Source.Ext]
                else:
                    # stop at no more rules
                    if LastTarget:
                        TargetList.add(str(LastTarget))
                    break

                FileType = RuleObject.SourceFileType

                # stop at STATIC_LIBRARY for library
                if Inf.LibraryClass and FileType == DataType.TAB_STATIC_LIBRARY:
                    if LastTarget:
                        TargetList.add(str(LastTarget))
                    break

                Target = RuleObject.Apply(Source)
                if not Target:
                    if LastTarget:
                        TargetList.add(str(LastTarget))
                    break
                elif not Target.Outputs:
                    # Only do build for target with outputs
                    TargetList.add(str(Target))

                # to avoid cyclic rule
                if FileType in RuleChain:
                    break

                RuleChain.append(FileType)
                SourceList.extend(Target.Outputs)
                LastTarget = Target
                FileType = DataType.TAB_UNKNOWN_FILE
                for Cmd in Target.Commands:
                    if "$(CP)" == Cmd.split()[0]:
                        CpTarget = Cmd.split()[2]
                        TargetList.add(CpTarget)

        return list(TargetList)

    ## SetDir()
    #
    #   @param  OutputDir           Output directory
    #   @param  FdfParser           FDF contents parser
    #   @param  Workspace           The directory of workspace
    #   @param  ArchList            The Arch list of platform
    #
    @staticmethod
    def SetDir (OutputDir, FdfParser, WorkSpace, ArchList):
        GenFdsGlobalVariable.VerboseLogger("GenFdsGlobalVariable.OutputDir:%s" % OutputDir)
        GenFdsGlobalVariable.FdfParser = FdfParser
        GenFdsGlobalVariable.WorkSpace = WorkSpace
        GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], DataType.TAB_FV_DIRECTORY)
        if not os.path.exists(GenFdsGlobalVariable.FvDir):
            os.makedirs(GenFdsGlobalVariable.FvDir)
        GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')
        if not os.path.exists(GenFdsGlobalVariable.FfsDir):
            os.makedirs(GenFdsGlobalVariable.FfsDir)

        #
        # Create FV Address inf file
        #
        GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')
        FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')
        #
        # Add [Options]
        #
        FvAddressFile.writelines("[options]" + DataType.TAB_LINE_BREAK)
        BsAddress = '0'
        for Arch in ArchList:
            if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress:
                BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress
                break

        FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
                                       BsAddress + \
                                       DataType.TAB_LINE_BREAK)

        RtAddress = '0'
        for Arch in reversed(ArchList):
            temp = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress
            if temp:
                RtAddress = temp
                break

        FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
                                       RtAddress + \
                                       DataType.TAB_LINE_BREAK)

        FvAddressFile.close()

    @staticmethod
    def SetEnv(FdfParser, WorkSpace, ArchList, GlobalData):
        GenFdsGlobalVariable.ModuleFile = WorkSpace.ModuleFile
        GenFdsGlobalVariable.FdfParser = FdfParser
        GenFdsGlobalVariable.WorkSpace = WorkSpace.Db
        GenFdsGlobalVariable.ArchList = ArchList
        GenFdsGlobalVariable.ToolChainTag = GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]
        GenFdsGlobalVariable.TargetName = GlobalData.gGlobalDefines["TARGET"]
        GenFdsGlobalVariable.ActivePlatform = GlobalData.gActivePlatform
        GenFdsGlobalVariable.ConfDir  = GlobalData.gConfDirectory
        GenFdsGlobalVariable.EnableGenfdsMultiThread = GlobalData.gEnableGenfdsMultiThread
        for Arch in ArchList:
            GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.normpath(
                os.path.join(GlobalData.gWorkspace,
                             WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],
                             GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory,
                             GlobalData.gGlobalDefines['TARGET'] +'_' + GlobalData.gGlobalDefines['TOOLCHAIN']))
            GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = os.path.normpath(
                             WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,
                             GlobalData.gGlobalDefines['TARGET'], GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory)
            GenFdsGlobalVariable.PlatformName = WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,
                                                                      GlobalData.gGlobalDefines['TARGET'],
                                                                      GlobalData.gGlobalDefines['TOOLCHAIN']].PlatformName
        GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], DataType.TAB_FV_DIRECTORY)
        if not os.path.exists(GenFdsGlobalVariable.FvDir):
            os.makedirs(GenFdsGlobalVariable.FvDir)
        GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')
        if not os.path.exists(GenFdsGlobalVariable.FfsDir):
            os.makedirs(GenFdsGlobalVariable.FfsDir)

        #
        # Create FV Address inf file
        #
        GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')
        FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')
        #
        # Add [Options]
        #
        FvAddressFile.writelines("[options]" + DataType.TAB_LINE_BREAK)
        BsAddress = '0'
        for Arch in ArchList:
            BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,
                                                                   GlobalData.gGlobalDefines['TARGET'],
                                                                   GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].BsBaseAddress
            if BsAddress:
                break

        FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
                                 BsAddress + \
                                 DataType.TAB_LINE_BREAK)

        RtAddress = '0'
        for Arch in reversed(ArchList):
            temp = GenFdsGlobalVariable.WorkSpace.BuildObject[
                GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],
                GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress
            if temp:
                RtAddress = temp
                break

        FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
                                 RtAddress + \
                                 DataType.TAB_LINE_BREAK)

        FvAddressFile.close()

    ## ReplaceWorkspaceMacro()
    #
    #   @param  String           String that may contain macro
    #
    @staticmethod
    def ReplaceWorkspaceMacro(String):
        String = mws.handleWsMacro(String)
        Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir)
        if os.path.exists(Str):
            if not os.path.isabs(Str):
                Str = os.path.abspath(Str)
        else:
            Str = mws.join(GenFdsGlobalVariable.WorkSpaceDir, String)
        return os.path.normpath(Str)

    ## Check if the input files are newer than output files
    #
    #   @param  Output          Path of output file
    #   @param  Input           Path list of input files
    #
    #   @retval True            if Output doesn't exist, or any Input is newer
    #   @retval False           if all Input is older than Output
    #
    @staticmethod
    def NeedsUpdate(Output, Input):
        if not os.path.exists(Output):
            return True
        # always update "Output" if no "Input" given
        if not Input:
            return True

        # if fdf file is changed after the 'Output" is generated, update the 'Output'
        OutputTime = os.path.getmtime(Output)
        if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime:
            return True

        for F in Input:
            # always update "Output" if any "Input" doesn't exist
            if not os.path.exists(F):
                return True
            # always update "Output" if any "Input" is newer than "Output"
            if os.path.getmtime(F) > OutputTime:
                return True
        return False

    @staticmethod
    def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,
                        GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=[], BuildNumber=None, DummyFile=None, IsMakefile=False):
        Cmd = ["GenSec"]
        if Type:
            Cmd += ("-s", Type)
        if CompressionType:
            Cmd += ("-c", CompressionType)
        if Guid:
            Cmd += ("-g", Guid)
        if DummyFile:
            Cmd += ("--dummy", DummyFile)
        if GuidHdrLen:
            Cmd += ("-l", GuidHdrLen)
        #Add each guided attribute
        for Attr in GuidAttr:
            Cmd += ("-r", Attr)
        #Section Align is only for dummy section without section type
        for SecAlign in InputAlign:
            Cmd += ("--sectionalign", SecAlign)

        CommandFile = Output + '.txt'
        if Ui:
            if IsMakefile:
                if Ui == "$(MODULE_NAME)":
                    Cmd += ('-n', Ui)
                else:
                    Cmd += ("-n", '"' + Ui + '"')
                Cmd += ("-o", Output)
                if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
                    GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())
            else:
                SectionData = array('B', [0, 0, 0, 0])
                SectionData.fromlist(array('B',Ui.encode('utf-16-le')).tolist())
                SectionData.append(0)
                SectionData.append(0)
                Len = len(SectionData)
                GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15)


                DirName = os.path.dirname(Output)
                if not CreateDirectory(DirName):
                    EdkLogger.error(None, FILE_CREATE_FAILURE, "Could not create directory %s" % DirName)
                else:
                    if DirName == '':
                        DirName = os.getcwd()
                    if not os.access(DirName, os.W_OK):
                        EdkLogger.error(None, PERMISSION_FAILURE, "Do not have write permission on directory %s" % DirName)

                try:
                    with open(Output, "wb") as Fd:
                        SectionData.tofile(Fd)
                        Fd.flush()
                except IOError as X:
                    EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData='IOError %s' % X)

        elif Ver:
            Cmd += ("-n", Ver)
            if BuildNumber:
                Cmd += ("-j", BuildNumber)
            Cmd += ("-o", Output)

            SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
            if IsMakefile:
                if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
                    GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())
            else:
                if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
                    return
                GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
        else:
            Cmd += ("-o", Output)
            Cmd += Input

            SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
            if IsMakefile:
                if sys.platform == "win32":
                    Cmd = ['if', 'exist', Input[0]] + Cmd
                else:
                    Cmd = ['-test', '-e', Input[0], "&&"] + Cmd
                if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
                    GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())
            elif GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
                GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
                GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
                if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and
                    GenFdsGlobalVariable.LargeFileInFvFlags):
                    GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True

    @staticmethod
    def GetAlignment (AlignString):
        if not AlignString:
            return 0
        if AlignString.endswith('K'):
            return int (AlignString.rstrip('K')) * 1024
        if AlignString.endswith('M'):
            return int (AlignString.rstrip('M')) * 1024 * 1024
        if AlignString.endswith('G'):
            return int (AlignString.rstrip('G')) * 1024 * 1024 * 1024
        return int (AlignString)

    @staticmethod
    def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,
                    SectionAlign=None, MakefilePath=None):
        Cmd = ["GenFfs", "-t", Type, "-g", Guid]
        mFfsValidAlign = ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"]
        if Fixed == True:
            Cmd.append("-x")
        if CheckSum:
            Cmd.append("-s")
        if Align:
            if Align not in mFfsValidAlign:
                Align = GenFdsGlobalVariable.GetAlignment (Align)
                for index in range(0, len(mFfsValidAlign) - 1):
                    if ((Align > GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index])) and (Align <= GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index + 1]))):
                        break
                Align = mFfsValidAlign[index + 1]
            Cmd += ("-a", Align)

        Cmd += ("-o", Output)
        for I in range(0, len(Input)):
            if MakefilePath:
                Cmd += ("-oi", Input[I])
            else:
                Cmd += ("-i", Input[I])
            if SectionAlign and SectionAlign[I]:
                Cmd += ("-n", SectionAlign[I])

        CommandFile = Output + '.txt'
        SaveFileOnChange(CommandFile, ' '.join(Cmd), False)

        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
        if MakefilePath:
            if (tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)) not in GenFdsGlobalVariable.FfsCmdDict:
                GenFdsGlobalVariable.FfsCmdDict[tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)] = MakefilePath
            GenFdsGlobalVariable.SecCmdList = []
            GenFdsGlobalVariable.CopyList = []
        else:
            if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
                return
            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")

    @staticmethod
    def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False,
                               AddressFile=None, MapFile=None, FfsList=[], FileSystemGuid=None):
        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList):
            return
        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))

        Cmd = ["GenFv"]
        if BaseAddress:
            Cmd += ("-r", BaseAddress)

        if ForceRebase == False:
            Cmd += ("-F", "FALSE")
        elif ForceRebase == True:
            Cmd += ("-F", "TRUE")

        if Capsule:
            Cmd.append("-c")
        if Dump:
            Cmd.append("-p")
        if AddressFile:
            Cmd += ("-a", AddressFile)
        if MapFile:
            Cmd += ("-m", MapFile)
        if FileSystemGuid:
            Cmd += ("-g", FileSystemGuid)
        Cmd += ("-o", Output)
        for I in Input:
            Cmd += ("-i", I)

        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV")

    @staticmethod
    def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False,
                              Strip=False, Replace=False, TimeStamp=None, Join=False,
                              Align=None, Padding=None, Convert=False, IsMakefile=False):
        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:
            return
        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))

        Cmd = ["GenFw"]
        if Type.lower() == "te":
            Cmd.append("-t")
        if SubType:
            Cmd += ("-e", SubType)
        if TimeStamp:
            Cmd += ("-s", TimeStamp)
        if Align:
            Cmd += ("-a", Align)
        if Padding:
            Cmd += ("-p", Padding)
        if Zero:
            Cmd.append("-z")
        if Strip:
            Cmd.append("-l")
        if Replace:
            Cmd.append("-r")
        if Join:
            Cmd.append("-j")
        if Convert:
            Cmd.append("-m")
        Cmd += ("-o", Output)
        Cmd += Input
        if IsMakefile:
            if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
                GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())
        else:
            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")

    @staticmethod
    def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None,
                        Revision=None, DeviceId=None, VendorId=None, IsMakefile=False):
        InputList = []
        Cmd = ["EfiRom"]
        if EfiInput:

            if Compress:
                Cmd.append("-ec")
            else:
                Cmd.append("-e")

            for EfiFile in EfiInput:
                Cmd.append(EfiFile)
                InputList.append (EfiFile)

        if BinaryInput:
            Cmd.append("-b")
            for BinFile in BinaryInput:
                Cmd.append(BinFile)
                InputList.append (BinFile)

        # Check List
        if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList) and not IsMakefile:
            return
        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList))

        if ClassCode:
            Cmd += ("-l", ClassCode)
        if Revision:
            Cmd += ("-r", Revision)
        if DeviceId:
            Cmd += ("-i", DeviceId)
        if VendorId:
            Cmd += ("-f", VendorId)

        Cmd += ("-o", Output)
        if IsMakefile:
            if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
                GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())
        else:
            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom")

    @staticmethod
    def GuidTool(Output, Input, ToolPath, Options='', returnValue=[], IsMakefile=False):
        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:
            return
        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))

        Cmd = [ToolPath, ]
        Cmd += Options.split(' ')
        Cmd += ("-o", Output)
        Cmd += Input
        if IsMakefile:
            if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
                GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())
        else:
            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue)

    @staticmethod
    def CallExternalTool (cmd, errorMess, returnValue=[]):

        if type(cmd) not in (tuple, list):
            GenFdsGlobalVariable.ErrorLogger("ToolError!  Invalid parameter type in call to CallExternalTool")

        if GenFdsGlobalVariable.DebugLevel != -1:
            cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel))
            GenFdsGlobalVariable.InfLogger (cmd)

        if GenFdsGlobalVariable.VerboseMode:
            cmd += ('-v',)
            GenFdsGlobalVariable.InfLogger (cmd)
        else:
            stdout.write ('#')
            stdout.flush()
            GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1
            if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0:
                stdout.write('\n')

        try:
            PopenObject = Popen(' '.join(cmd), stdout=PIPE, stderr=PIPE, shell=True)
        except Exception as X:
            EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))
        (out, error) = PopenObject.communicate()

        while PopenObject.returncode is None:
            PopenObject.wait()
        if returnValue != [] and returnValue[0] != 0:
            #get command return value
            returnValue[0] = PopenObject.returncode
            return
        if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1:
            GenFdsGlobalVariable.InfLogger ("Return Value = %d" % PopenObject.returncode)
            GenFdsGlobalVariable.InfLogger(out.decode(encoding='utf-8', errors='ignore'))
            GenFdsGlobalVariable.InfLogger(error.decode(encoding='utf-8', errors='ignore'))
            if PopenObject.returncode != 0:
                print("###", cmd)
                EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess)

    @staticmethod
    def VerboseLogger (msg):
        EdkLogger.verbose(msg)

    @staticmethod
    def InfLogger (msg):
        EdkLogger.info(msg)

    @staticmethod
    def ErrorLogger (msg, File=None, Line=None, ExtraData=None):
        EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData)

    @staticmethod
    def DebugLogger (Level, msg):
        EdkLogger.debug(Level, msg)

    ## MacroExtend()
    #
    #   @param  Str           String that may contain macro
    #   @param  MacroDict     Dictionary that contains macro value pair
    #
    @staticmethod
    def MacroExtend (Str, MacroDict=None, Arch=DataType.TAB_COMMON):
        if Str is None:
            return None

        Dict = {'$(WORKSPACE)': GenFdsGlobalVariable.WorkSpaceDir,
#                '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,
                '$(TARGET)': GenFdsGlobalVariable.TargetName,
                '$(TOOL_CHAIN_TAG)': GenFdsGlobalVariable.ToolChainTag,
                '$(SPACE)': ' '
               }

        if Arch != DataType.TAB_COMMON and Arch in GenFdsGlobalVariable.ArchList:
            OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch]
        else:
            OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]]

        Dict['$(OUTPUT_DIRECTORY)'] = OutputDir

        if MacroDict:
            Dict.update(MacroDict)

        for key in Dict:
            if Str.find(key) >= 0:
                Str = Str.replace (key, Dict[key])

        if Str.find('$(ARCH)') >= 0:
            if len(GenFdsGlobalVariable.ArchList) == 1:
                Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0])
            else:
                EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str)

        return Str

    ## GetPcdValue()
    #
    #   @param  PcdPattern           pattern that labels a PCD.
    #
    @staticmethod
    def GetPcdValue (PcdPattern):
        if PcdPattern is None:
            return None
        if PcdPattern.startswith('PCD('):
            PcdPair = PcdPattern[4:].rstrip(')').strip().split('.')
        else:
            PcdPair = PcdPattern.strip().split('.')
        TokenSpace = PcdPair[0]
        TokenCName = PcdPair[1]

        for Arch in GenFdsGlobalVariable.ArchList:
            Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
            PcdDict = Platform.Pcds
            for Key in PcdDict:
                PcdObj = PcdDict[Key]
                if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
                    if PcdObj.Type != DataType.TAB_PCDS_FIXED_AT_BUILD:
                        EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
                    if PcdObj.DatumType != DataType.TAB_VOID:
                        EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)

                    return PcdObj.DefaultValue

            for Package in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform,
                                                                         Arch,
                                                                         GenFdsGlobalVariable.TargetName,
                                                                         GenFdsGlobalVariable.ToolChainTag):
                PcdDict = Package.Pcds
                for Key in PcdDict:
                    PcdObj = PcdDict[Key]
                    if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
                        if PcdObj.Type != DataType.TAB_PCDS_FIXED_AT_BUILD:
                            EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
                        if PcdObj.DatumType != DataType.TAB_VOID:
                            EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)

                        return PcdObj.DefaultValue

        return ''

## FindExtendTool()
#
#  Find location of tools to process data
#
#  @param  KeyStringList    Filter for inputs of section generation
#  @param  CurrentArchList  Arch list
#  @param  NameGuid         The Guid name
#
def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):
    if GenFdsGlobalVariable.GuidToolDefinition:
        if NameGuid in GenFdsGlobalVariable.GuidToolDefinition:
            return GenFdsGlobalVariable.GuidToolDefinition[NameGuid]

    ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf")))
    ToolDef = ToolDefObj.ToolDef
    ToolDb = ToolDef.ToolsDefTxtDatabase
    # if user not specify filter, try to deduce it from global data.
    if KeyStringList is None or KeyStringList == []:
        Target = GenFdsGlobalVariable.TargetName
        ToolChain = GenFdsGlobalVariable.ToolChainTag
        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)
        KeyStringList = [Target + '_' + ToolChain + '_' + CurrentArchList[0]]
        for Arch in CurrentArchList:
            if Target + '_' + ToolChain + '_' + Arch not in KeyStringList:
                KeyStringList.append(Target + '_' + ToolChain + '_' + Arch)

    ToolPathTmp = None
    ToolOption = None
    for Arch in CurrentArchList:
        MatchItem = None
        MatchPathItem = None
        MatchOptionsItem = None
        for KeyString in KeyStringList:
            KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_')
            if KeyStringArch != Arch:
                continue
            for Item in ToolDef.ToolsDefTxtDictionary:
                if len(Item.split('_')) < 5:
                    continue
                ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item.split('_')
                if ItemTarget == DataType.TAB_STAR:
                    ItemTarget = KeyStringBuildTarget
                if ItemToolChain == DataType.TAB_STAR:
                    ItemToolChain = KeyStringToolChain
                if ItemArch == DataType.TAB_STAR:
                    ItemArch = KeyStringArch
                if ItemTarget != KeyStringBuildTarget:
                    continue
                if ItemToolChain != KeyStringToolChain:
                    continue
                if ItemArch != KeyStringArch:
                    continue
                if ItemAttr != DataType.TAB_GUID:
                    # Not GUID attribute
                    continue
                if ToolDef.ToolsDefTxtDictionary[Item].lower() != NameGuid.lower():
                    # No GUID value match
                    continue
                if MatchItem:
                    if MatchItem.split('_')[3] == ItemTool:
                        # Tool name is the same
                        continue
                    if CalculatePriorityValue(MatchItem) > CalculatePriorityValue(Item):
                        # Current MatchItem is higher priority than new match item
                        continue
                MatchItem = Item
            if not MatchItem:
                continue
            ToolName = MatchItem.split('_')[3]
            for Item in ToolDef.ToolsDefTxtDictionary:
                if len(Item.split('_')) < 5:
                    continue
                ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item.split('_')
                if ItemTarget == DataType.TAB_STAR:
                    ItemTarget = KeyStringBuildTarget
                if ItemToolChain == DataType.TAB_STAR:
                    ItemToolChain = KeyStringToolChain
                if ItemArch == DataType.TAB_STAR:
                    ItemArch = KeyStringArch
                if ItemTarget != KeyStringBuildTarget:
                    continue
                if ItemToolChain != KeyStringToolChain:
                    continue
                if ItemArch != KeyStringArch:
                    continue
                if ItemTool != ToolName:
                    continue
                if ItemAttr == 'PATH':
                    if MatchPathItem:
                        if CalculatePriorityValue(MatchPathItem) <= CalculatePriorityValue(Item):
                            MatchPathItem = Item
                    else:
                        MatchPathItem = Item
                if ItemAttr == 'FLAGS':
                    if MatchOptionsItem:
                        if CalculatePriorityValue(MatchOptionsItem) <= CalculatePriorityValue(Item):
                            MatchOptionsItem = Item
                    else:
                        MatchOptionsItem = Item
        if MatchPathItem:
            ToolPathTmp = ToolDef.ToolsDefTxtDictionary[MatchPathItem]
        if MatchOptionsItem:
            ToolOption = ToolDef.ToolsDefTxtDictionary[MatchOptionsItem]

    for Arch in CurrentArchList:
        MatchItem = None
        MatchPathItem = None
        MatchOptionsItem = None
        for KeyString in KeyStringList:
            KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_')
            if KeyStringArch != Arch:
                continue
            Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, KeyStringBuildTarget, KeyStringToolChain]
            for Item in Platform.BuildOptions:
                if len(Item[1].split('_')) < 5:
                    continue
                ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item[1].split('_')
                if ItemTarget == DataType.TAB_STAR:
                    ItemTarget = KeyStringBuildTarget
                if ItemToolChain == DataType.TAB_STAR:
                    ItemToolChain = KeyStringToolChain
                if ItemArch == DataType.TAB_STAR:
                    ItemArch = KeyStringArch
                if ItemTarget != KeyStringBuildTarget:
                    continue
                if ItemToolChain != KeyStringToolChain:
                    continue
                if ItemArch != KeyStringArch:
                    continue
                if ItemAttr != DataType.TAB_GUID:
                    # Not GUID attribute match
                    continue
                if Platform.BuildOptions[Item].lower() != NameGuid.lower():
                    # No GUID value match
                    continue
                if MatchItem:
                    if MatchItem[1].split('_')[3] == ItemTool:
                        # Tool name is the same
                        continue
                    if CalculatePriorityValue(MatchItem[1]) > CalculatePriorityValue(Item[1]):
                        # Current MatchItem is higher priority than new match item
                        continue
                MatchItem = Item
            if not MatchItem:
                continue
            ToolName = MatchItem[1].split('_')[3]
            for Item in Platform.BuildOptions:
                if len(Item[1].split('_')) < 5:
                    continue
                ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item[1].split('_')
                if ItemTarget == DataType.TAB_STAR:
                    ItemTarget = KeyStringBuildTarget
                if ItemToolChain == DataType.TAB_STAR:
                    ItemToolChain = KeyStringToolChain
                if ItemArch == DataType.TAB_STAR:
                    ItemArch = KeyStringArch
                if ItemTarget != KeyStringBuildTarget:
                    continue
                if ItemToolChain != KeyStringToolChain:
                    continue
                if ItemArch != KeyStringArch:
                    continue
                if ItemTool != ToolName:
                    continue
                if ItemAttr == 'PATH':
                    if MatchPathItem:
                        if CalculatePriorityValue(MatchPathItem[1]) <= CalculatePriorityValue(Item[1]):
                            MatchPathItem = Item
                    else:
                        MatchPathItem = Item
                if ItemAttr == 'FLAGS':
                    if MatchOptionsItem:
                        if CalculatePriorityValue(MatchOptionsItem[1]) <= CalculatePriorityValue(Item[1]):
                            MatchOptionsItem = Item
                    else:
                        MatchOptionsItem = Item
    if MatchPathItem:
        ToolPathTmp = Platform.BuildOptions[MatchPathItem]
    if MatchOptionsItem:
        ToolOption = Platform.BuildOptions[MatchOptionsItem]
    GenFdsGlobalVariable.GuidToolDefinition[NameGuid] = (ToolPathTmp, ToolOption)
    return ToolPathTmp, ToolOption
