## @file
# generate flash image
#
#  Copyright (c) 2007 - 2018, 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
#
from __future__ import print_function
from __future__ import absolute_import
from optparse import OptionParser
import sys
import Common.LongFilePathOs as os
import linecache
from . import FdfParser
import Common.BuildToolError as BuildToolError
from .GenFdsGlobalVariable import GenFdsGlobalVariable
from Workspace.WorkspaceDatabase import WorkspaceDatabase
from Workspace.BuildClassObject import PcdClassObject
from . import RuleComplexFile
from .EfiSection import EfiSection
from io import BytesIO
import Common.TargetTxtClassObject as TargetTxtClassObject
import Common.ToolDefClassObject as ToolDefClassObject
from Common.DataType import *
import Common.GlobalData as GlobalData
from Common import EdkLogger
from Common.StringUtils import *
from Common.Misc import DirCache, PathClass
from Common.Misc import SaveFileOnChange
from Common.Misc import ClearDuplicatedInf
from Common.Misc import GuidStructureStringToGuidString
from Common.BuildVersion import gBUILD_VERSION
from Common.MultipleWorkspace import MultipleWorkspace as mws
from . import FfsFileStatement
import glob
from struct import unpack
from Common.GlobalData import gGuidPattern

## Version and Copyright
versionNumber = "1.0" + ' ' + gBUILD_VERSION
__version__ = "%prog Version " + versionNumber
__copyright__ = "Copyright (c) 2007 - 2018, Intel Corporation  All rights reserved."

## Tool entrance method
#
# This method mainly dispatch specific methods per the command line options.
# If no error found, return zero value so the caller of this tool can know
# if it's executed successfully or not.
#
#   @retval 0     Tool was successful
#   @retval 1     Tool failed
#
def main():
    global Options
    Options = myOptionParser()

    global Workspace
    Workspace = ""
    ArchList = None
    ReturnCode = 0

    EdkLogger.Initialize()
    try:
        if Options.verbose is not None:
            EdkLogger.SetLevel(EdkLogger.VERBOSE)
            GenFdsGlobalVariable.VerboseMode = True

        if Options.FixedAddress is not None:
            GenFdsGlobalVariable.FixedLoadAddress = True

        if Options.quiet is not None:
            EdkLogger.SetLevel(EdkLogger.QUIET)
        if Options.debug is not None:
            EdkLogger.SetLevel(Options.debug + 1)
            GenFdsGlobalVariable.DebugLevel = Options.debug
        else:
            EdkLogger.SetLevel(EdkLogger.INFO)

        if (Options.Workspace is None):
            EdkLogger.error("GenFds", OPTION_MISSING, "WORKSPACE not defined",
                            ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")
        elif not os.path.exists(Options.Workspace):
            EdkLogger.error("GenFds", PARAMETER_INVALID, "WORKSPACE is invalid",
                            ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")
        else:
            Workspace = os.path.normcase(Options.Workspace)
            GenFdsGlobalVariable.WorkSpaceDir = Workspace
            if 'EDK_SOURCE' in os.environ:
                GenFdsGlobalVariable.EdkSourceDir = os.path.normcase(os.environ['EDK_SOURCE'])
            if (Options.debug):
                GenFdsGlobalVariable.VerboseLogger("Using Workspace:" + Workspace)
            if Options.GenfdsMultiThread:
                GenFdsGlobalVariable.EnableGenfdsMultiThread = True
        os.chdir(GenFdsGlobalVariable.WorkSpaceDir)

        # set multiple workspace
        PackagesPath = os.getenv("PACKAGES_PATH")
        mws.setWs(GenFdsGlobalVariable.WorkSpaceDir, PackagesPath)

        if (Options.filename):
            FdfFilename = Options.filename
            FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename)

            if FdfFilename[0:2] == '..':
                FdfFilename = os.path.realpath(FdfFilename)
            if not os.path.isabs(FdfFilename):
                FdfFilename = mws.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename)
            if not os.path.exists(FdfFilename):
                EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=FdfFilename)

            GenFdsGlobalVariable.FdfFile = FdfFilename
            GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime(FdfFilename)
        else:
            EdkLogger.error("GenFds", OPTION_MISSING, "Missing FDF filename")

        if (Options.BuildTarget):
            GenFdsGlobalVariable.TargetName = Options.BuildTarget

        if (Options.ToolChain):
            GenFdsGlobalVariable.ToolChainTag = Options.ToolChain

        if (Options.activePlatform):
            ActivePlatform = Options.activePlatform
            ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform)

            if ActivePlatform[0:2] == '..':
                ActivePlatform = os.path.realpath(ActivePlatform)

            if not os.path.isabs (ActivePlatform):
                ActivePlatform = mws.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform)

            if not os.path.exists(ActivePlatform)  :
                EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!")
        else:
            EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform")

        GlobalData.BuildOptionPcd     = Options.OptionPcd if Options.OptionPcd else {}
        GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform))

        if (Options.ConfDirectory):
            # Get alternate Conf location, if it is absolute, then just use the absolute directory name
            ConfDirectoryPath = os.path.normpath(Options.ConfDirectory)
            if ConfDirectoryPath.startswith('"'):
                ConfDirectoryPath = ConfDirectoryPath[1:]
            if ConfDirectoryPath.endswith('"'):
                ConfDirectoryPath = ConfDirectoryPath[:-1]
            if not os.path.isabs(ConfDirectoryPath):
                # Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE
                # This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf
                ConfDirectoryPath = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ConfDirectoryPath)
        else:
            if "CONF_PATH" in os.environ:
                ConfDirectoryPath = os.path.normcase(os.environ["CONF_PATH"])
            else:
                # Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf
                ConfDirectoryPath = mws.join(GenFdsGlobalVariable.WorkSpaceDir, 'Conf')
        GenFdsGlobalVariable.ConfDir = ConfDirectoryPath
        if not GlobalData.gConfDirectory:
            GlobalData.gConfDirectory = GenFdsGlobalVariable.ConfDir
        BuildConfigurationFile = os.path.normpath(os.path.join(ConfDirectoryPath, "target.txt"))
        if os.path.isfile(BuildConfigurationFile) == True:
            TargetTxt = TargetTxtClassObject.TargetTxtClassObject()
            TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)
            # if no build target given in command line, get it from target.txt
            if not GenFdsGlobalVariable.TargetName:
                BuildTargetList = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET]
                if len(BuildTargetList) != 1:
                    EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for Target.")
                GenFdsGlobalVariable.TargetName = BuildTargetList[0]

            # if no tool chain given in command line, get it from target.txt
            if not GenFdsGlobalVariable.ToolChainTag:
                ToolChainList = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG]
                if ToolChainList is None or len(ToolChainList) == 0:
                    EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build.")
                if len(ToolChainList) != 1:
                    EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for ToolChain.")
                GenFdsGlobalVariable.ToolChainTag = ToolChainList[0]
        else:
            EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile)

        #Set global flag for build mode
        GlobalData.gIgnoreSource = Options.IgnoreSources

        if Options.Macros:
            for Pair in Options.Macros:
                if Pair.startswith('"'):
                    Pair = Pair[1:]
                if Pair.endswith('"'):
                    Pair = Pair[:-1]
                List = Pair.split('=')
                if len(List) == 2:
                    if not List[1].strip():
                        EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="No Value given for Macro %s" %List[0])
                    if List[0].strip() == "EFI_SOURCE":
                        GlobalData.gEfiSource = List[1].strip()
                        GlobalData.gGlobalDefines["EFI_SOURCE"] = GlobalData.gEfiSource
                        continue
                    elif List[0].strip() == "EDK_SOURCE":
                        GlobalData.gEdkSource = List[1].strip()
                        GlobalData.gGlobalDefines["EDK_SOURCE"] = GlobalData.gEdkSource
                        continue
                    elif List[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]:
                        GlobalData.gGlobalDefines[List[0].strip()] = List[1].strip()
                    else:
                        GlobalData.gCommandLineDefines[List[0].strip()] = List[1].strip()
                else:
                    GlobalData.gCommandLineDefines[List[0].strip()] = "TRUE"
        os.environ["WORKSPACE"] = Workspace

        # Use the -t and -b option as gGlobalDefines's TOOLCHAIN and TARGET if they are not defined
        if "TARGET" not in GlobalData.gGlobalDefines:
            GlobalData.gGlobalDefines["TARGET"] = GenFdsGlobalVariable.TargetName
        if "TOOLCHAIN" not in GlobalData.gGlobalDefines:
            GlobalData.gGlobalDefines["TOOLCHAIN"] = GenFdsGlobalVariable.ToolChainTag
        if "TOOL_CHAIN_TAG" not in GlobalData.gGlobalDefines:
            GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = GenFdsGlobalVariable.ToolChainTag

        """call Workspace build create database"""
        GlobalData.gDatabasePath = os.path.normpath(os.path.join(ConfDirectoryPath, GlobalData.gDatabasePath))
        BuildWorkSpace = WorkspaceDatabase(GlobalData.gDatabasePath)
        BuildWorkSpace.InitDatabase()

        #
        # Get files real name in workspace dir
        #
        GlobalData.gAllFiles = DirCache(Workspace)
        GlobalData.gWorkspace = Workspace

        if (Options.archList) :
            ArchList = Options.archList.split(',')
        else:
#            EdkLogger.error("GenFds", OPTION_MISSING, "Missing build ARCH")
            ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, Options.BuildTarget, Options.ToolChain].SupArchList

        TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, Options.BuildTarget, Options.ToolChain].SupArchList) & set(ArchList)
        if len(TargetArchList) == 0:
            EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON].SupArchList)))

        for Arch in ArchList:
            GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].OutputDirectory)
            GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].PlatformName

        if (Options.outputDir):
            OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(Options.outputDir)
            if not os.path.isabs (OutputDirFromCommandLine):
                OutputDirFromCommandLine = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, OutputDirFromCommandLine)
            for Arch in ArchList:
                GenFdsGlobalVariable.OutputDirDict[Arch] = OutputDirFromCommandLine
        else:
            for Arch in ArchList:
                GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag)

        for Key in GenFdsGlobalVariable.OutputDirDict:
            OutputDir = GenFdsGlobalVariable.OutputDirDict[Key]
            if OutputDir[0:2] == '..':
                OutputDir = os.path.realpath(OutputDir)

            if OutputDir[1] != ':':
                OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir)

            if not os.path.exists(OutputDir):
                EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=OutputDir)
            GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir

        """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """
        FdfParserObj = FdfParser.FdfParser(FdfFilename)
        FdfParserObj.ParseFile()

        if FdfParserObj.CycleReferenceCheck():
            EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file")

        if (Options.uiFdName) :
            if Options.uiFdName.upper() in FdfParserObj.Profile.FdDict:
                GenFds.OnlyGenerateThisFd = Options.uiFdName
            else:
                EdkLogger.error("GenFds", OPTION_VALUE_INVALID,
                                "No such an FD in FDF file: %s" % Options.uiFdName)

        if (Options.uiFvName) :
            if Options.uiFvName.upper() in FdfParserObj.Profile.FvDict:
                GenFds.OnlyGenerateThisFv = Options.uiFvName
            else:
                EdkLogger.error("GenFds", OPTION_VALUE_INVALID,
                                "No such an FV in FDF file: %s" % Options.uiFvName)

        if (Options.uiCapName) :
            if Options.uiCapName.upper() in FdfParserObj.Profile.CapsuleDict:
                GenFds.OnlyGenerateThisCap = Options.uiCapName
            else:
                EdkLogger.error("GenFds", OPTION_VALUE_INVALID,
                                "No such a Capsule in FDF file: %s" % Options.uiCapName)

        GenFdsGlobalVariable.WorkSpace = BuildWorkSpace
        if ArchList is not None:
            GenFdsGlobalVariable.ArchList = ArchList

        # Dsc Build Data will handle Pcd Settings from CommandLine.

        """Modify images from build output if the feature of loading driver at fixed address is on."""
        if GenFdsGlobalVariable.FixedLoadAddress:
            GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform)

        # Record the FV Region info that may specific in the FD
        if FdfParserObj.Profile.FvDict and FdfParserObj.Profile.FdDict:
            for Fv in FdfParserObj.Profile.FvDict:
                FvObj = FdfParserObj.Profile.FvDict[Fv]
                for Fd in FdfParserObj.Profile.FdDict:
                    FdObj = FdfParserObj.Profile.FdDict[Fd]
                    for RegionObj in FdObj.RegionList:
                        if RegionObj.RegionType != BINARY_FILE_TYPE_FV:
                            continue
                        for RegionData in RegionObj.RegionDataList:
                            if FvObj.UiFvName.upper() == RegionData.upper():
                                if FvObj.FvRegionInFD:
                                    if FvObj.FvRegionInFD != RegionObj.Size:
                                        EdkLogger.error("GenFds", FORMAT_INVALID, "The FV %s's region is specified in multiple FD with different value." %FvObj.UiFvName)
                                else:
                                    FvObj.FvRegionInFD = RegionObj.Size
                                    RegionObj.BlockInfoOfRegion(FdObj.BlockSizeList, FvObj)

        """Call GenFds"""
        GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)

        """Generate GUID cross reference file"""
        GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList, FdfParserObj)

        """Display FV space info."""
        GenFds.DisplayFvSpaceInfo(FdfParserObj)

    except FdfParser.Warning as X:
        EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False)
        ReturnCode = FORMAT_INVALID
    except FatalError as X:
        if Options.debug is not None:
            import traceback
            EdkLogger.quiet(traceback.format_exc())
        ReturnCode = X.args[0]
    except:
        import traceback
        EdkLogger.error(
                    "\nPython",
                    CODE_ERROR,
                    "Tools code failure",
                    ExtraData="Please send email to edk2-devel@lists.01.org for help, attaching following call stack trace!\n",
                    RaiseError=False
                    )
        EdkLogger.quiet(traceback.format_exc())
        ReturnCode = CODE_ERROR
    finally:
        ClearDuplicatedInf()
    return ReturnCode

gParamCheck = []
def SingleCheckCallback(option, opt_str, value, parser):
    if option not in gParamCheck:
        setattr(parser.values, option.dest, value)
        gParamCheck.append(option)
    else:
        parser.error("Option %s only allows one instance in command line!" % option)

## Parse command line options
#
# Using standard Python module optparse to parse command line option of this tool.
#
#   @retval Opt   A optparse.Values object containing the parsed options
#   @retval Args  Target of build command
#
def myOptionParser():
    usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\""
    Parser = OptionParser(usage=usage, description=__copyright__, version="%prog " + str(versionNumber))
    Parser.add_option("-f", "--file", dest="filename", type="string", help="Name of FDF file to convert", action="callback", callback=SingleCheckCallback)
    Parser.add_option("-a", "--arch", dest="archList", help="comma separated list containing one or more of: IA32, X64, IPF, ARM, AARCH64 or EBC which should be built, overrides target.txt?s TARGET_ARCH")
    Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
    Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")
    Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")
    Parser.add_option("-p", "--platform", type="string", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.",
                      action="callback", callback=SingleCheckCallback)
    Parser.add_option("-w", "--workspace", type="string", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE",
                      action="callback", callback=SingleCheckCallback)
    Parser.add_option("-o", "--outputDir", type="string", dest="outputDir", help="Name of Build Output directory",
                      action="callback", callback=SingleCheckCallback)
    Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.")
    Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Build the FV image using the [FV] section named by UiFvName")
    Parser.add_option("-C", "--CapsuleImage", dest="uiCapName", help="Build the Capsule image using the [Capsule] section named by UiCapName")
    Parser.add_option("-b", "--buildtarget", type="string", dest="BuildTarget", help="Set the build TARGET, overrides target.txt TARGET setting.",
                      action="callback", callback=SingleCheckCallback)
    Parser.add_option("-t", "--tagname", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.",
                      action="callback", callback=SingleCheckCallback)
    Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")
    Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.")
    Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")
    Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files")
    Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ")
    Parser.add_option("--genfds-multi-thread", action="store_true", dest="GenfdsMultiThread", default=False, help="Enable GenFds multi thread to generate ffs file.")

    (Options, args) = Parser.parse_args()
    return Options

## The class implementing the EDK2 flash image generation process
#
#   This process includes:
#       1. Collect workspace information, includes platform and module information
#       2. Call methods of Fd class to generate FD
#       3. Call methods of Fv class to generate FV that not belong to FD
#
class GenFds :
    FdfParsef = None
    OnlyGenerateThisFd = None
    OnlyGenerateThisFv = None
    OnlyGenerateThisCap = None

    ## GenFd()
    #
    #   @param  OutputDir           Output directory
    #   @param  FdfParser           FDF contents parser
    #   @param  Workspace           The directory of workspace
    #   @param  ArchList            The Arch list of platform
    #
    def GenFd (OutputDir, FdfParser, WorkSpace, ArchList):
        GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList)

        GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")
        if GenFds.OnlyGenerateThisCap is not None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict:
            CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[GenFds.OnlyGenerateThisCap.upper()]
            if CapsuleObj is not None:
                CapsuleObj.GenCapsule()
                return

        if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict:
            FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]
            if FdObj is not None:
                FdObj.GenFd()
                return
        elif GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisFv is None:
            for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():
                FdObj.GenFd()

        GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ")
        if GenFds.OnlyGenerateThisFv is not None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict:
            FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[GenFds.OnlyGenerateThisFv.upper()]
            if FvObj is not None:
                Buffer = BytesIO()
                FvObj.AddToBuffer(Buffer)
                Buffer.close()
                return
        elif GenFds.OnlyGenerateThisFv is None:
            for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict.values():
                Buffer = BytesIO('')
                FvObj.AddToBuffer(Buffer)
                Buffer.close()

        if GenFds.OnlyGenerateThisFv is None and GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisCap is None:
            if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:
                GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")
                for CapsuleObj in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.values():
                    CapsuleObj.GenCapsule()

            if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:
                GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!")
                for OptRomObj in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.values():
                    OptRomObj.AddToBuffer(None)
    @staticmethod
    def GenFfsMakefile(OutputDir, FdfParser, WorkSpace, ArchList, GlobalData):
        GenFdsGlobalVariable.SetEnv(FdfParser, WorkSpace, ArchList, GlobalData)
        for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():
            FdObj.GenFd(Flag=True)

        for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict.values():
            FvObj.AddToBuffer(Buffer=None, Flag=True)

        if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:
            for OptRomObj in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.values():
                OptRomObj.AddToBuffer(Buffer=None, Flag=True)

        return GenFdsGlobalVariable.FfsCmdDict

    ## GetFvBlockSize()
    #
    #   @param  FvObj           Whose block size to get
    #   @retval int             Block size value
    #
    def GetFvBlockSize(FvObj):
        DefaultBlockSize = 0x1
        FdObj = None
        if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict:
            FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]
        if FdObj is None:
            for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():
                for ElementRegion in ElementFd.RegionList:
                    if ElementRegion.RegionType == BINARY_FILE_TYPE_FV:
                        for ElementRegionData in ElementRegion.RegionDataList:
                            if ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName:
                                if FvObj.BlockSizeList != []:
                                    return FvObj.BlockSizeList[0][0]
                                else:
                                    return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)
            if FvObj.BlockSizeList != []:
                return FvObj.BlockSizeList[0][0]
            return DefaultBlockSize
        else:
            for ElementRegion in FdObj.RegionList:
                    if ElementRegion.RegionType == BINARY_FILE_TYPE_FV:
                        for ElementRegionData in ElementRegion.RegionDataList:
                            if ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName:
                                if FvObj.BlockSizeList != []:
                                    return FvObj.BlockSizeList[0][0]
                                else:
                                    return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)
            return DefaultBlockSize

    ## DisplayFvSpaceInfo()
    #
    #   @param  FvObj           Whose block size to get
    #   @retval None
    #
    def DisplayFvSpaceInfo(FdfParser):

        FvSpaceInfoList = []
        MaxFvNameLength = 0
        for FvName in FdfParser.Profile.FvDict:
            if len(FvName) > MaxFvNameLength:
                MaxFvNameLength = len(FvName)
            FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map')
            if os.path.exists(FvSpaceInfoFileName):
                FileLinesList = linecache.getlines(FvSpaceInfoFileName)
                TotalFound = False
                Total = ''
                UsedFound = False
                Used = ''
                FreeFound = False
                Free = ''
                for Line in FileLinesList:
                    NameValue = Line.split('=')
                    if len(NameValue) == 2:
                        if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE':
                            TotalFound = True
                            Total = NameValue[1].strip()
                        if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE':
                            UsedFound = True
                            Used = NameValue[1].strip()
                        if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE':
                            FreeFound = True
                            Free = NameValue[1].strip()

                if TotalFound and UsedFound and FreeFound:
                    FvSpaceInfoList.append((FvName, Total, Used, Free))

        GenFdsGlobalVariable.InfLogger('\nFV Space Information')
        for FvSpaceInfo in FvSpaceInfoList:
            Name = FvSpaceInfo[0]
            TotalSizeValue = long(FvSpaceInfo[1], 0)
            UsedSizeValue = long(FvSpaceInfo[2], 0)
            FreeSizeValue = long(FvSpaceInfo[3], 0)
            if UsedSizeValue == TotalSizeValue:
                Percentage = '100'
            else:
                Percentage = str((UsedSizeValue + 0.0) / TotalSizeValue)[0:4].lstrip('0.')

            GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + Percentage + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free')

    ## PreprocessImage()
    #
    #   @param  BuildDb         Database from build meta data files
    #   @param  DscFile         modules from dsc file will be preprocessed
    #   @retval None
    #
    def PreprocessImage(BuildDb, DscFile):
        PcdDict = BuildDb.BuildObject[DscFile, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Pcds
        PcdValue = ''
        for Key in PcdDict:
            PcdObj = PcdDict[Key]
            if PcdObj.TokenCName == 'PcdBsBaseAddress':
                PcdValue = PcdObj.DefaultValue
                break

        if PcdValue == '':
            return

        Int64PcdValue = long(PcdValue, 0)
        if Int64PcdValue == 0 or Int64PcdValue < -1:
            return

        TopAddress = 0
        if Int64PcdValue > 0:
            TopAddress = Int64PcdValue

        ModuleDict = BuildDb.BuildObject[DscFile, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Modules
        for Key in ModuleDict:
            ModuleObj = BuildDb.BuildObject[Key, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
            print(ModuleObj.BaseName + ' ' + ModuleObj.ModuleType)

    def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj):
        GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")
        GuidXRefFile = BytesIO('')
        PkgGuidDict = {}
        GuidDict = {}
        ModuleList = []
        FileGuidList = []
        GuidPattern = gGuidPattern
        for Arch in ArchList:
            PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
            PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag)
            for P in PkgList:
                PkgGuidDict.update(P.Guids)
            for Name, Guid in PlatformDataBase.Pcds:
                Pcd = PlatformDataBase.Pcds[Name, Guid]
                if Pcd.Type in [TAB_PCDS_DYNAMIC_HII, TAB_PCDS_DYNAMIC_EX_HII]:
                    for SkuId in Pcd.SkuInfoList:
                        Sku = Pcd.SkuInfoList[SkuId]
                        if Sku.VariableGuid and Sku.VariableGuid in PkgGuidDict.keys():
                            GuidDict[Sku.VariableGuid] = PkgGuidDict[Sku.VariableGuid]
            for ModuleFile in PlatformDataBase.Modules:
                Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
                if Module in ModuleList:
                    continue
                else:
                    ModuleList.append(Module)
                GuidMatch = GuidPattern.match(ModuleFile.BaseName)
                if GuidMatch is not None:
                    GuidXRefFile.write("%s %s\n" % (ModuleFile.BaseName, Module.BaseName))
                else:
                    GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName))
                for key, item in Module.Protocols.items():
                    GuidDict[key] = item
                for key, item in Module.Guids.items():
                    GuidDict[key] = item
                for key, item in Module.Ppis.items():
                    GuidDict[key] = item
            for FvName in FdfParserObj.Profile.FvDict:
                for FfsObj in FdfParserObj.Profile.FvDict[FvName].FfsList:
                    if not isinstance(FfsObj, FfsFileStatement.FileStatement):
                        InfPath = PathClass(NormPath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, FfsObj.InfFileName)))
                        FdfModule = BuildDb.BuildObject[InfPath, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
                        if FdfModule in ModuleList:
                            continue
                        else:
                            ModuleList.append(FdfModule)
                        GuidXRefFile.write("%s %s\n" % (FdfModule.Guid, FdfModule.BaseName))
                        for key, item in FdfModule.Protocols.items():
                            GuidDict[key] = item
                        for key, item in FdfModule.Guids.items():
                            GuidDict[key] = item
                        for key, item in FdfModule.Ppis.items():
                            GuidDict[key] = item
                    else:
                        FileStatementGuid = FfsObj.NameGuid
                        if FileStatementGuid in FileGuidList:
                            continue
                        else:
                            FileGuidList.append(FileStatementGuid)
                        Name = []
                        FfsPath = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')
                        FfsPath = glob.glob(os.path.join(FfsPath, FileStatementGuid) + '*')
                        if not FfsPath:
                            continue
                        if not os.path.exists(FfsPath[0]):
                            continue
                        MatchDict = {}
                        ReFileEnds = re.compile('\S+(.ui)$|\S+(fv.sec.txt)$|\S+(.pe32.txt)$|\S+(.te.txt)$|\S+(.pic.txt)$|\S+(.raw.txt)$|\S+(.ffs.txt)$')
                        FileList = os.listdir(FfsPath[0])
                        for File in FileList:
                            Match = ReFileEnds.search(File)
                            if Match:
                                for Index in range(1, 8):
                                    if Match.group(Index) and Match.group(Index) in MatchDict:
                                        MatchDict[Match.group(Index)].append(File)
                                    elif Match.group(Index):
                                        MatchDict[Match.group(Index)] = [File]
                        if not MatchDict:
                            continue
                        if '.ui' in MatchDict:
                            for File in MatchDict['.ui']:
                                with open(os.path.join(FfsPath[0], File), 'rb') as F:
                                    F.read()
                                    length = F.tell()
                                    F.seek(4)
                                    TmpStr = unpack('%dh' % ((length - 4) / 2), F.read())
                                    Name = ''.join(chr(c) for c in TmpStr[:-1])
                        else:
                            FileList = []
                            if 'fv.sec.txt' in MatchDict:
                                FileList = MatchDict['fv.sec.txt']
                            elif '.pe32.txt' in MatchDict:
                                FileList = MatchDict['.pe32.txt']
                            elif '.te.txt' in MatchDict:
                                FileList = MatchDict['.te.txt']
                            elif '.pic.txt' in MatchDict:
                                FileList = MatchDict['.pic.txt']
                            elif '.raw.txt' in MatchDict:
                                FileList = MatchDict['.raw.txt']
                            elif '.ffs.txt' in MatchDict:
                                FileList = MatchDict['.ffs.txt']
                            else:
                                pass
                            for File in FileList:
                                with open(os.path.join(FfsPath[0], File), 'r') as F:
                                    Name.append((F.read().split()[-1]))
                        if not Name:
                            continue

                        Name = ' '.join(Name) if isinstance(Name, type([])) else Name
                        GuidXRefFile.write("%s %s\n" %(FileStatementGuid, Name))

       # Append GUIDs, Protocols, and PPIs to the Xref file
        GuidXRefFile.write("\n")
        for key, item in GuidDict.items():
            GuidXRefFile.write("%s %s\n" % (GuidStructureStringToGuidString(item).upper(), key))

        if GuidXRefFile.getvalue():
            SaveFileOnChange(GuidXRefFileName, GuidXRefFile.getvalue(), False)
            GenFdsGlobalVariable.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName)
        elif os.path.exists(GuidXRefFileName):
            os.remove(GuidXRefFileName)
        GuidXRefFile.close()

    ##Define GenFd as static function
    GenFd = staticmethod(GenFd)
    GetFvBlockSize = staticmethod(GetFvBlockSize)
    DisplayFvSpaceInfo = staticmethod(DisplayFvSpaceInfo)
    PreprocessImage = staticmethod(PreprocessImage)
    GenerateGuidXRefFile = staticmethod(GenerateGuidXRefFile)

if __name__ == '__main__':
    r = main()
    ## 0-127 is a safe return range, and 1 is a standard default error
    if r < 0 or r > 127: r = 1
    sys.exit(r)

