## @file InfPomAlignmentMisc.py
# This file contained the routines for InfPomAlignment
#
# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#

'''
InfPomAlignmentMisc
'''

##
# Import modules
#
import Logger.Log as Logger
from Library import DataType as DT
from Library.Misc import ConvertArchList
from Object.POM.ModuleObject import BinaryFileObject
from Object.POM import CommonObject
from Library.StringUtils import FORMAT_INVALID
from Library.Misc import CheckGuidRegFormat
from Logger import StringTable as ST


## GenModuleHeaderUserExt
#
#
def GenModuleHeaderUserExt(DefineObj, ArchString):
    DefinesDictNew = {}
    EdkReleaseVersion = DefineObj.GetEdkReleaseVersion()
    Shadow = DefineObj.GetShadow()
    DpxSource = DefineObj.GetDpxSource()
    PciVendorId = DefineObj.GetPciVendorId()
    PciDeviceId = DefineObj.GetPciDeviceId()
    PciClassCode = DefineObj.GetPciClassCode()
    PciRevision = DefineObj.GetPciRevision()
    PciCompress = DefineObj.GetPciCompress()
    CustomMakefile = DefineObj.GetCustomMakefile()
    UefiHiiResourceSection = DefineObj.GetUefiHiiResourceSection()

    if EdkReleaseVersion is not None:
        Name = DT.TAB_INF_DEFINES_EDK_RELEASE_VERSION
        Value = EdkReleaseVersion.GetValue()
        Statement = _GenInfDefineStateMent(EdkReleaseVersion.Comments.GetHeaderComments(),
                                           Name,
                                           Value,
                                           EdkReleaseVersion.Comments.GetTailComments())
        DefinesDictNew[Statement] = ArchString

    if Shadow is not None:
        Name = DT.TAB_INF_DEFINES_SHADOW
        Value = Shadow.GetValue()
        Statement = _GenInfDefineStateMent(Shadow.Comments.GetHeaderComments(),
                                           Name,
                                           Value,
                                           Shadow.Comments.GetTailComments())
        DefinesDictNew[Statement] = ArchString

    if DpxSource is not None:
        Name = DT.TAB_INF_DEFINES_DPX_SOURCE
        for DpxSourceItem in DpxSource:
            Value = DpxSourceItem[0]
            Statement = _GenInfDefineStateMent(DpxSourceItem[1].GetHeaderComments(),
                                               Name,
                                               Value,
                                               DpxSourceItem[1].GetTailComments())
            DefinesDictNew[Statement] = ArchString

    if PciVendorId is not None:
        Name = DT.TAB_INF_DEFINES_PCI_VENDOR_ID
        Value = PciVendorId.GetValue()
        Statement = _GenInfDefineStateMent(PciVendorId.Comments.GetHeaderComments(),
                                           Name,
                                           Value,
                                           PciVendorId.Comments.GetTailComments())
        DefinesDictNew[Statement] = ArchString

    if PciDeviceId is not None:
        Name = DT.TAB_INF_DEFINES_PCI_DEVICE_ID
        Value = PciDeviceId.GetValue()
        Statement = _GenInfDefineStateMent(PciDeviceId.Comments.GetHeaderComments(),
                                           Name,
                                           Value,
                                           PciDeviceId.Comments.GetTailComments())
        DefinesDictNew[Statement] = ArchString

    if PciClassCode is not None:
        Name = DT.TAB_INF_DEFINES_PCI_CLASS_CODE
        Value = PciClassCode.GetValue()
        Statement = _GenInfDefineStateMent(PciClassCode.Comments.GetHeaderComments(),
                                           Name,
                                           Value,
                                           PciClassCode.Comments.GetTailComments())
        DefinesDictNew[Statement] = ArchString

    if PciRevision is not None:
        Name = DT.TAB_INF_DEFINES_PCI_REVISION
        Value = PciRevision.GetValue()
        Statement = _GenInfDefineStateMent(PciRevision.Comments.GetHeaderComments(),
                                           Name,
                                           Value,
                                           PciRevision.Comments.GetTailComments())
        DefinesDictNew[Statement] = ArchString

    if PciCompress is not None:
        Name = DT.TAB_INF_DEFINES_PCI_COMPRESS
        Value = PciCompress.GetValue()
        Statement = _GenInfDefineStateMent(PciCompress.Comments.GetHeaderComments(),
                                           Name,
                                           Value,
                                           PciCompress.Comments.GetTailComments())
        DefinesDictNew[Statement] = ArchString

    if len(CustomMakefile) >= 1:
        for CustomMakefileItem in CustomMakefile:
            Name = DT.TAB_INF_DEFINES_CUSTOM_MAKEFILE
            #
            # Not with Feature Flag Expression
            #
            if len(CustomMakefileItem) == 3:
                if CustomMakefileItem[0] != '':
                    Value = CustomMakefileItem[0] + ' | ' + CustomMakefileItem[1]
                else:
                    Value = CustomMakefileItem[1]

                Comments = CustomMakefileItem[2]
                Statement = _GenInfDefineStateMent(Comments.GetHeaderComments(),
                                                   Name,
                                                   Value,
                                                   Comments.GetTailComments())

            DefinesDictNew[Statement] = ArchString

    if UefiHiiResourceSection is not None:
        Name = DT.TAB_INF_DEFINES_UEFI_HII_RESOURCE_SECTION
        Value = UefiHiiResourceSection.GetValue()
        HeaderComment = UefiHiiResourceSection.Comments.GetHeaderComments()
        TailComment = UefiHiiResourceSection.Comments.GetTailComments()
        Statement = _GenInfDefineStateMent(HeaderComment,
                                           Name,
                                           Value,
                                           TailComment)
        DefinesDictNew[Statement] = ""

    return DefinesDictNew


## Generate the define statement that will be put into userextension
#  Not support comments.
#
# @param HeaderComment: the original header comment (# not removed)
# @param Name: the definition keyword, should not be empty or none
# @param Value: the definition keyword value
# @param TailComment: the original Tail comment (# not removed)
#
# @return: the regenerated define statement
#
def _GenInfDefineStateMent(HeaderComment, Name, Value, TailComment):
    Logger.Debug(5, HeaderComment + TailComment)
    Statement = '%s = %s' % (Name, Value)

    return Statement

## GenBinaryData
#
#
def GenBinaryData(BinaryData, BinaryObj, BinariesDict, AsBuildIns, BinaryFileObjectList, \
                  SupArchList, BinaryModule, DecObjList=None):
    if BinaryModule:
        pass
    OriSupArchList = SupArchList
    for Item in BinaryData:
        ItemObj = BinaryObj[Item][0][0]
        if ItemObj.GetType() not in DT.BINARY_FILE_TYPE_UI_LIST + DT.BINARY_FILE_TYPE_VER_LIST:
            TagName = ItemObj.GetTagName()
            Family = ItemObj.GetFamily()
        else:
            TagName = ''
            Family = ''

        FFE = ItemObj.GetFeatureFlagExp()

        #
        # If have architecturie specified, then use the specified architecturie;
        # If the section tag does not have an architecture modifier or the modifier is "common" (case in-sensitive),
        # and the VALID_ARCHITECTURES comment exists, the list from the VALID_ARCHITECTURES comment
        # can be used for the attribute.
        # If both not have VALID_ARCHITECTURE comment and no architecturie specified, then keep it empty.
        #
        SupArchList = sorted(ConvertArchList(ItemObj.GetSupArchList()))
        if len(SupArchList) == 1 and SupArchList[0] == 'COMMON':
            if not (len(OriSupArchList) == 1 or OriSupArchList[0] == 'COMMON'):
                SupArchList = OriSupArchList
            else:
                SupArchList = ['COMMON']

        FileNameObj = CommonObject.FileNameObject()
        FileNameObj.SetFileType(ItemObj.GetType())
        FileNameObj.SetFilename(ItemObj.GetFileName())
        FileNameObj.SetFeatureFlag(FFE)
        #
        # Get GUID value of the GUID CName in the DEC file
        #
        if ItemObj.GetType() == DT.SUBTYPE_GUID_BINARY_FILE_TYPE:
            if not CheckGuidRegFormat(ItemObj.GetGuidValue()):
                if not DecObjList:
                    if DT.TAB_HORIZON_LINE_SPLIT in ItemObj.GetGuidValue() or \
                        DT.TAB_COMMA_SPLIT in ItemObj.GetGuidValue():
                        Logger.Error("\nMkPkg",
                                 FORMAT_INVALID,
                                 ST.ERR_DECPARSE_DEFINE_PKGGUID,
                                 ExtraData=ItemObj.GetGuidValue(),
                                 RaiseError=True)
                    else:
                        Logger.Error("\nMkPkg",
                                     FORMAT_INVALID,
                                     ST.ERR_UNI_SUBGUID_VALUE_DEFINE_DEC_NOT_FOUND % \
                                     (ItemObj.GetGuidValue()),
                                     RaiseError=True)
                else:
                    for DecObj in DecObjList:
                        for GuidObj in DecObj.GetGuidList():
                            if GuidObj.GetCName() == ItemObj.GetGuidValue():
                                FileNameObj.SetGuidValue(GuidObj.GetGuid())
                                break

                    if not FileNameObj.GetGuidValue():
                        Logger.Error("\nMkPkg",
                                         FORMAT_INVALID,
                                         ST.ERR_DECPARSE_CGUID_NOT_FOUND % \
                                         (ItemObj.GetGuidValue()),
                                         RaiseError=True)
            else:
                FileNameObj.SetGuidValue(ItemObj.GetGuidValue().strip())

        FileNameObj.SetSupArchList(SupArchList)
        FileNameList = [FileNameObj]

        BinaryFile = BinaryFileObject()
        BinaryFile.SetFileNameList(FileNameList)
        BinaryFile.SetAsBuiltList(AsBuildIns)
        BinaryFileObjectList.append(BinaryFile)

        SupArchStr = ' '.join(SupArchList)
        Key = (ItemObj.GetFileName(), ItemObj.GetType(), FFE, SupArchStr)
        ValueItem = (ItemObj.GetTarget(), Family, TagName, '')
        if Key in BinariesDict:
            ValueList = BinariesDict[Key]
            ValueList.append(ValueItem)
            BinariesDict[Key] = ValueList
        else:
            BinariesDict[Key] = [ValueItem]

    return BinariesDict, AsBuildIns, BinaryFileObjectList
